home *** CD-ROM | disk | FTP | other *** search
/ TestDrive Windows 1993 Fall / TestDrive Windows 1993 Fall.iso / dbase / dtl / report.cod < prev    next >
Encoding:
Text File  |  1993-03-09  |  71.6 KB  |  2,900 lines

  1. //
  2. // Module Name: REPORT.COD
  3. // Description: Define report program structure.
  4. //
  5. //
  6. Report (.frg) Program Template
  7. ------------------------------
  8. $Version: $
  9. Copyright (c) 1991 Borland International, Inc.
  10. {
  11.  include "report.def";
  12.  include "builtin.def";
  13.  
  14.  if getenv("dtl_debug") then
  15.    debug(2)
  16.    breakpoint( pick_debug )
  17.  endif
  18.  
  19.  var  bnl_formname,     // Name of BNL file to newframe if argument() has value
  20.       arg_list;
  21.  
  22.  arg_list = argument()
  23.  if arg_list != "" then
  24.    bnl_formname = token( ",", arg_list, 1 )
  25.    if !newframe( bnl_formname ) then
  26.      return -1;
  27.    endif
  28.  endif
  29.  
  30. //
  31. // Enum string constants for international translation
  32. //
  33. enum
  34.     wrong_class = "Can't use REPORT.GEN on non-report objects.  ",
  35.     demo_string  = "dBASE IV SAMPLE REPORT - FOR EVALUATION PURPOSES ONLY",
  36.     increase_page = "Increase the page length for this report.",
  37.     demo_version = 0;
  38.  
  39. enum    FIRST_GEN = 2;
  40.  
  41. enum    CHARACTER_TYPE = 67,
  42.         DATE_TYPE,
  43.         FLOAT_TYPE = 70,
  44.         LOGICAL_TYPE = 76,
  45.         MEMO_TYPE,
  46.         NUMERIC_TYPE = 78;
  47.  
  48. enum    AVERAGE_OP = 0,
  49.         COUNT_OP = 1,
  50.         MAX_OP,
  51.         MIN_OP,
  52.         SUM_OP,
  53.         STD_DEV_OP,
  54.         VARIANCE_OP;
  55.  
  56.     if frame_class != report then
  57.         pause(wrong_class + any_key)
  58.         return 0
  59.     endif
  60.  
  61. var
  62. // temporary variables
  63.     count,x,a,i,ni,j,k,temp,temp2,
  64. // global variables
  65.      rptname,   // Report name
  66.  default_drive, // dBASE default drive
  67.      isfirst,   // first system memvar? (handles commas)
  68.      isnew,     // is this a new band?
  69.      isopen,    // is the band open?
  70.      priv_vars, // system memvars list
  71.     priv_vars2, // if FLD_EXPRESSION is broken into 2 strings
  72.      bandedit,  // word wrap off or on
  73.      bandgrp,   // GROUP id for bands
  74.      bandhgt,   // band row position plus height plus one
  75.      bandlen2,  // length of page header (0 if band is closed)
  76.   bandspacing2, // spacing on page header band
  77.      bandlen50, // length of detail band        "
  78.    bandspacing, // spacing on detail band
  79.      bandlen98, // length of page footer        "
  80.  bandspacing98, // spacing on footer band
  81.      bandtype,  // type of band ie. page footer, report intro, etc.
  82.  band_previous, // previous bandtype
  83.      length,    // length of field or text
  84.      maxgrp,    // maximum number of bands
  85.      isrepo,    // is there report intro/summary bands
  86.      maxrow,    // maximum row
  87.      nextrow,   // next row when looking ahead ie. ++<cursor>
  88. current_column, // current text or field plus length
  89.      bsrv,      // beginning of band suppress repeated value
  90.      xsrv,      // current suppress repeated value var
  91.      xsum,      // current "noname" summary field
  92.      xxsum,     // subset of either an average, std. deviation or variance
  93.      samerow,   // flag set for items occuring on the same row
  94.      bandrow,   // band row plus one
  95.  first_combine, // text or field is the first in the chain of combined data
  96.      combine,   // combine fields flag
  97.  suppress_line, // if the text "Page no." appears first on the line
  98.   previous_row, // previous elements' row
  99.     pre_type,   // previous element type was field or text
  100.     next_type,
  101.    inner_loop,  // elements inside the band encountered
  102.   optl_heading, // flag to test whether optional heading has been output
  103. is_rintro_open, // is the Report Intro band open
  104.  is_rsumm_open, // is the Report Summary band open
  105. number_of_open_group_intros,   // none open, Grphead procedure is suppressed
  106. number_of_open_group_summarys, // none open, Grpfoot procedure is suppressed
  107. is_page_header_open, // if Page Header band is open
  108. number_of_reset_on_page, // summary fields reset on page
  109. number_of_fld_suppress,  // suppressed fields
  110. intro_band_one_height,   // footer widow checking for
  111. intro_band_two_height,   // dBASE III PLUS reports
  112. number_of_word_wrap_bands,
  113. number_of_group_calc_fields,
  114. number_of_group_footer_fields,
  115. number_of_group_intro_each,
  116. current_group_footer_field,
  117. number_of_begin_new_pages,
  118. retain_previous,
  119. external_define,
  120. blankable_row,
  121. left_delimiter,
  122. right_delimiter,
  123. delimit_flag,
  124. ruler_flag,
  125. previous_indent,
  126. previous_lmargin,
  127. previous_rmargin,
  128. previous_tabs,
  129. line_one_length
  130. ;
  131.     default_drive = STRSET(_defdrive)
  132.     rptname = FRAME_PATH + NAME
  133.     if not FILEOK(rptname) then
  134.         if FILEDRIVE(NAME) || !default_drive then
  135.             rptname=NAME
  136.         else
  137.             rptname=default_drive + ":" + NAME
  138.         endif
  139.     endif
  140.  
  141.     if not CREATE(rptname+".FRG") then
  142.         PAUSE(fileroot(rptname)+".FRG"+read_only+any_key)
  143.         return 0
  144.     endif
  145.  
  146.     pre_pass();
  147.  
  148. // variable initializations
  149.     bandrow=0
  150.     bsrv=0
  151.     combine=0
  152.     current_column=0
  153.     first_combine=1
  154.     isopen=0
  155.     maxrow=0
  156.     nextrow=0
  157.     optl_heading=0
  158.     previous_row=0
  159.     left_delimiter="\""
  160.     right_delimiter="\""
  161.     delimit_flag=0
  162.     samerow=0
  163.     xsrv=0
  164.     xsum=0
  165.     xxsum=0
  166.     isrepo=0
  167.     is_rintro_open=0
  168.     bandlen2=0
  169.     is_page_header_open=0
  170.     bandlen50=0
  171.     current_group_footer_field=0
  172.     number_of_begin_new_pages=0
  173.     number_of_group_footer_fields=0
  174.     number_of_group_intro_each=0
  175.     number_of_open_group_intros=0
  176.     number_of_open_group_summarys=0
  177.     number_of_word_wrap_bands=0
  178.     bandlen98=0
  179.     bandspacing=0
  180.     bandspacing98=0
  181.     is_rsumm_open=0
  182.     intro_band_one_height=0
  183.     intro_band_two_height=0
  184.     ruler_flag=1
  185.     line_one_length=0;  }
  186. * Program............: {rptname}.FRG
  187. * Date...............: {LTRIM(SUBSTR(DATE(),1,8))}
  188. * Versions...........: dBASE IV, Report {db_version_no}
  189. *
  190. * Notes:
  191. * ------
  192. * Prior to running this procedure with the DO command
  193. * it is necessary use LOCATE because the CONTINUE
  194. * statement is in the main loop.
  195. *
  196. *-- Parameters
  197. PARAMETERS gl_noeject, gl_plain, gl_summary, gc_heading, gc_extra
  198. ** The first three parameters are of type Logical.
  199. ** The fourth parameter is a string.  The fifth is extra.
  200. {
  201.     if dBASE_III_PLUS == FIRST_GEN then
  202.         a=", _plength, _ploffset";
  203.     else
  204.         a="";
  205.     endif
  206. }
  207. PRIVATE _peject{a}, _wrap, ll_heading
  208. ll_heading = .F.
  209.  
  210. *-- Test for no records found
  211. IF EOF() .OR. .NOT. FOUND()
  212.    RETURN
  213. ENDIF
  214.  
  215. *-- turn word wrap mode off
  216. _wrap=.F.
  217.  
  218. {       report_setup();
  219. }
  220. IF _plength < {tb_margin(bandlen2,bandspacing2)} \
  221. + {tb_margin(bandlen98,bandspacing98)} + 2
  222.    SET DEVICE TO SCREEN
  223.    DEFINE WINDOW gw_report FROM 7,17 TO 11,62 DOUBLE
  224.    ACTIVATE WINDOW gw_report
  225.    @ 0,1 SAY "{increase_page}"
  226.    @ 2,1 SAY "{any_key}"
  227.    x=INKEY(0)
  228.    DEACTIVATE WINDOW gw_report
  229.    RELEASE WINDOW gw_report
  230.    RETURN
  231. ENDIF
  232.  
  233. _plineno=0          && set lines to zero
  234. {   if dBASE_III_PLUS == FIRST_GEN then  }
  235.  
  236. *-- dBASE III PLUS report setup
  237. {
  238.     case PRINT_NEW_PAGE of
  239.     0: a="\"AFTER\""
  240.     1: a="\"BEFORE\""
  241.     2: a="\"BOTH\""
  242.     3: a="\"NONE\""
  243.     endcase
  244. }
  245. _peject={a}
  246. _plength={PRINT_PAGE_LENGTH}
  247. _ploffset={(!PRINT_LEFT_OFFSET) ? 0 : PRINT_LEFT_OFFSET}
  248.  
  249. *-- PLAIN option to screen only
  250. IF gl_plain
  251.    IF SET("PRINT") = "OFF" .AND. SET("ALTERNATE") = "OFF"
  252.       gl_noeject=.T.
  253.    ENDIF
  254. ENDIF
  255.  
  256. {   endif   }
  257. *-- NOEJECT parameter
  258. IF gl_noeject
  259.    IF _peject="BEFORE"
  260.       _peject="NONE"
  261.    ENDIF
  262.    IF _peject="BOTH"
  263.       _peject="AFTER"
  264.    ENDIF
  265. ENDIF
  266.  
  267. *-- Set-up environment
  268. ON ESCAPE DO Prnabort
  269. IF SET("TALK")="ON"
  270.    SET TALK OFF
  271.    gc_talk="ON"
  272. ELSE
  273.    gc_talk="OFF"
  274. ENDIF
  275. gc_space=SET("SPACE")
  276. SET SPACE OFF
  277. gc_time=TIME()      && system time for predefined field
  278. gd_date=DATE()      && system date  "    "    "     "
  279. gl_fandl=.F.        && first and last page flag
  280. {       if number_of_group_intro_each then }
  281. gl_intros=.F.       && flag for group intros on each page
  282. {       endif   }
  283. gl_prntflg=.T.      && Continue printing flag
  284. gl_widow=.T.        && flag for checking widow bands
  285. gn_length=LEN(gc_heading)  && store length of the HEADING
  286. gn_level=2          && current band being processed
  287. gn_page=_pageno     && grab current page number
  288. gn_pspace=_pspacing && get current print spacing
  289.  
  290. {   init_group_footer_vars();
  291.     init_calculated_vars(); }
  292.  
  293. *-- Set up procedure for page break
  294. gn_atline=_plength - {tb_margin(bandlen98,bandspacing98)}
  295. ON PAGE AT LINE gn_atline EJECT PAGE
  296.  
  297. *-- Print Report
  298.  
  299. PRINTJOB
  300.  
  301. {   if number_of_begin_new_pages then   }
  302. gl_newpage=.T.      && ok to begin band on new page
  303.  
  304. {   endif
  305.     init_group_break_vars()
  306.     init_summary_vars()
  307.     init_suppress_repeated_value_vars()
  308.     assign_calculated_vars()
  309.     assign_summary_vars()
  310.     if isrepo && is_rintro_open && not FRAME_PAGEHEADINGS then  }
  311. DO Rintro
  312.  
  313. *-- reset page number in case report intro spanned two pages
  314. _pageno=gn_page
  315.  
  316. {   endif   }
  317. IF gl_plain
  318.    ON PAGE AT LINE gn_atline DO Pgplain
  319. ELSE
  320.    ON PAGE AT LINE gn_atline DO Pgfoot
  321. ENDIF
  322.  
  323. {   if has_headers() then   }
  324. DO Pghead
  325.  
  326. {   endif   }
  327. gl_fandl=.T.        && first physical page started
  328.  
  329. {   if isrepo && is_rintro_open && FRAME_PAGEHEADINGS then  }
  330. DO Rintro
  331. {       if number_of_begin_new_pages then   }
  332. gl_newpage=.F.
  333. {       endif  }
  334.  
  335. {   endif
  336.     if number_of_open_group_intros then }
  337. DO Grphead
  338. {       if number_of_group_intro_each then }
  339. gl_intros=.F.
  340. {       endif   }
  341.  
  342. {   endif   }
  343. *-- File Loop
  344. DO WHILE FOUND() .AND. .NOT. EOF() .AND. gl_prntflg
  345. {   lmarg(4)
  346. //
  347. // If there are group bands
  348. // set up the CASE structure to test
  349. // the group band values
  350. //
  351.     if (number_of_open_group_intros || number_of_open_group_summarys) then }
  352. DO CASE
  353. {       build_case_statement(); }
  354. OTHERWISE
  355.    gn_level=0
  356. ENDCASE
  357. *-- test whether an expression didn't match
  358. IF gn_level <> 0
  359. {       if number_of_open_group_summarys then   }
  360.    DO Grpfoot WITH 100-gn_level
  361. {       endif   }
  362.    DO Grpinit
  363. ENDIF
  364. {       if number_of_open_group_intros then }
  365. *-- Repeat group intros
  366. IF gn_level <> 0
  367.    DO Grphead
  368. ENDIF
  369. {       endif
  370.         if number_of_group_intro_each then }
  371. gl_intros=.F.
  372. {       endif
  373.     endif   }
  374. gn_level=0
  375. {   if bandlen50 then   }
  376. *-- Detail lines
  377. IF gl_summary
  378.    DO Upd_Vars
  379. ELSE
  380.    DO __Detail
  381. ENDIF
  382. {   else    }
  383. DO Upd_Vars
  384. {   endif}
  385. gl_widow=.T.         && enable widow checking
  386. CONTINUE
  387. {   if number_of_open_group_intros || number_of_open_group_summarys then
  388.         increment_group_by_record_vars()
  389.     endif
  390.     lmarg(1);   }
  391. ENDDO
  392.  
  393. IF gl_prntflg
  394. //
  395. // If there are group bands
  396. //
  397. {   if maxgrp > 3 then  }
  398.    gn_level=3
  399. {       if number_of_open_group_summarys then   }
  400.    DO Grpfoot WITH 97
  401. {       endif
  402.     endif   }
  403. //
  404. // Report summary
  405. //
  406. {   if isrepo && is_rsumm_open then }
  407.    DO Rsumm
  408. {   endif
  409.     if bandlen98 then
  410.         if !is_rsumm_open then  }
  411.    gl_fandl=.F.     && last page finished
  412. {       endif   }
  413.    IF _plineno <= gn_atline
  414.       EJECT PAGE
  415.    ENDIF
  416. {   endif   }
  417. ELSE
  418. {   if isrepo && is_rsumm_open then
  419.         if maxgrp > 3 then  }
  420.    gn_level=3
  421. {       endif   }
  422.    DO Rsumm
  423. {   endif   }
  424.    DO Reset
  425.    RETURN
  426. ENDIF
  427.  
  428. ON PAGE
  429.  
  430. ENDPRINTJOB
  431.  
  432. DO Reset
  433. RETURN
  434. * EOP: {rptname}.FRG
  435. {   output_proc_gheight();  }
  436.  
  437. *-- Update summary fields and/or calculated fields.
  438. PROCEDURE Upd_Vars
  439. {   update_summary_and_calc_vars(); }
  440. RETURN
  441. * EOP: Upd_Vars
  442.  
  443. *-- Set flag to get out of DO WHILE loop when escape is pressed.
  444. PROCEDURE Prnabort
  445. gl_prntflg=.F.
  446. RETURN
  447. * EOP: Prnabort
  448.  
  449. {   if number_of_open_group_intros
  450.      || number_of_open_group_summarys then }
  451. *-- Reset group break variables.  Reinit summary
  452. *-- fields with reset set to a particular group band.
  453. PROCEDURE Grpinit
  454. {       reinit_group_variables(); }
  455. RETURN
  456. * EOP: Grpinit
  457.  
  458. {   endif
  459.     if number_of_reset_on_page || number_of_fld_suppress then   }
  460. *-- Reset summary fields (on page) and suppress repeated values.
  461. PROCEDURE Pageinit
  462. {       reinit_page_variables(); }
  463. RETURN
  464. * EOP: Pageinit
  465.  
  466. {   endif
  467.     if (number_of_open_group_intros
  468.      || number_of_open_group_summarys) then
  469.         output_group_calls();
  470.     endif
  471.     if external_define then
  472.         fileerase(rptname+".grp");
  473.         APPEND(rptname+".FRG");
  474.     endif
  475.     output_band_procs();    }
  476.  
  477. *-- Process page break when PLAIN option is used.
  478. PROCEDURE Pgplain
  479. PRIVATE _box
  480. EJECT PAGE
  481. {   if number_of_reset_on_page
  482.     || number_of_fld_suppress then  }
  483. IF gl_fandl
  484.    DO Pageinit
  485. ENDIF
  486. {   endif   }
  487. RETURN
  488. * EOP: Pgplain
  489.  
  490. *-- Reset dBASE environment prior to calling report
  491. PROCEDURE Reset
  492. SET SPACE &gc_space.
  493. SET TALK &gc_talk.
  494. ON ESCAPE
  495. ON PAGE
  496. RETURN
  497. * EOP: Reset
  498.  
  499. {
  500. return 0;
  501. //--------------------------------
  502. // End of main template procedure
  503. // User defined functions follow
  504. //--------------------------------
  505. define output_band_procs()
  506. //
  507. // Main loop which outputs the procedures for all the bands
  508. // and the contents of each band (also setup code).
  509. //
  510.     bandtype=99
  511. //
  512.     foreach ELEMENT ecursor
  513.         inner_loop=0
  514.         pre_type=0
  515.         next_type=0
  516. //
  517. // List type is a BAND?
  518. //
  519.         if ELEMENT_TYPE == @Band_Element then
  520.             begin_new_band(ecursor)
  521.             loop
  522.         else
  523.             ++count;
  524.         endif
  525.  
  526. do while ELEMENT_TYPE != @Band_Element && !eoc(ecursor)
  527.   inner_loop=1;
  528. //
  529.   if ELEMENT_TYPE == @Fld_Element then
  530.     if FLD_SUPPRESS then
  531.       ++xsrv;
  532.     endif
  533.  
  534.     retain_previous=0;
  535.     if GROUP > 50 then
  536.       retain_previous=retain_previous_value(ecursor)
  537.     endif
  538.     if retain_previous then
  539.       ++current_group_footer_field;
  540.     endif
  541.  
  542.     if !FLD_FIELDNAME && FLD_FIELDTYPE == Summ_data then
  543.       ++xsum;
  544.     endif
  545.   endif
  546. //
  547.   if FLD_HIDDEN || not isopen goto noprint endif
  548. //
  549. // Text or Field item begins on new row
  550. //
  551.   if ELEMENT_TYPE == @Text_Element || ELEMENT_TYPE == @Fld_Element then
  552.     if !pre_type || previous_row != Row_Positn then
  553.       samerow=0;
  554.       combine=0;
  555.       first_combine=1;
  556.     endif
  557.   endif
  558. //
  559.   if !optl_heading
  560.    && Row_Positn > bandrow+1
  561.    && bandtype == Page_Header then
  562.     if maxrow < bandrow+1 then }
  563. ?
  564.  
  565. {       ++maxrow;
  566.     endif   }
  567. *-- Print HEADING parameter - no items on line one
  568. IF .NOT. gl_plain
  569.    ?? gc_heading FUNCTION "I;V"+LTRIM(STR(_rmargin - _lmargin))
  570. ENDIF
  571.  
  572. {   optl_heading=1;
  573.   endif
  574. //
  575. // Output carriage returns for dBASE report
  576. //
  577.   if !bandedit then
  578. nextline1:
  579.     if maxrow < Row_Positn then }
  580. ?
  581. {     ++maxrow;
  582.       goto nextline1;
  583.     endif
  584.   else
  585.     if blankable_row && previous_row < Row_Positn then
  586.       blankable_row=0;
  587.       lmarg(1); }
  588. ENDIF
  589. {   endif
  590.     if (previous_row < Row_Positn) && (ELEMENT_TYPE == @Fld_Element
  591.     || ELEMENT_TYPE == @Text_Element) then
  592.       blankable_row=check4blank(ecursor);
  593.       if blankable_row then
  594.         if conditional_if_for_blank_line(ecursor) then
  595.           isnew=1;
  596.           lmarg(4);
  597.         endif
  598.       endif
  599.     endif
  600.     maxrow=Row_Positn;
  601.   endif
  602. //
  603. // Insert heading code for items on line one
  604. //
  605.     if line_one_length
  606.      && dBASE_III_PLUS != FIRST_GEN
  607.      && bandtype == Page_Header
  608.      && Row_Positn == bandrow+1 then    }
  609. *-- Print HEADING parameter - if it doesn't fit on line one
  610. *-- Value added to gn_length is the last column on line one times two
  611. IF .NOT. gl_plain .AND. gn_length + {line_one_length * 2} > ln_width
  612.    ?? gc_heading FUNCTION "I;V"+LTRIM(STR(ln_width))
  613.    ?
  614.    ll_heading = .F.
  615. ENDIF
  616.  
  617. {       line_one_length=0;
  618.     endif
  619. //
  620.   pre_type=0;
  621.   next_type=0;
  622.   ++ecursor;
  623.   nextrow=Row_Positn;
  624.   if ELEMENT_TYPE == @Text_Element
  625.   || ELEMENT_TYPE == @Fld_Element then
  626.     next_type=1;
  627.   endif
  628.   --ecursor;
  629. //
  630.   case ELEMENT_TYPE of
  631.   @Text_Element:
  632. //
  633.     x=Col_Positn;
  634.     i=LEN(Text_Item);
  635.     ni=0;
  636.     pre_type=1;
  637.     if i == 237 then
  638.       foreach Text_Item fcursor in ecursor
  639.         if ni then
  640.           i=i+LEN(Text_Item);
  641.           temp=Text_Item;
  642.         endif
  643.         ++ni;
  644.       next
  645.     endif
  646.     current_column=x+i;
  647.     set_combine_flag(ecursor);
  648.     ++ecursor;
  649.     if (bandtype == Page_Header || bandtype == Page_Footer)
  650.       && ELEMENT_TYPE == @Fld_Element
  651.       && nextrow == maxrow then
  652.         if FLD_FIELDTYPE == Pred_data
  653.             && FLD_PREDEFINE == 3 then
  654.           --ecursor;
  655.           if SUBSTR(UPPER(Text_Item),1,4) == "PAGE" then
  656.             if previous_row == Row_Positn then
  657.                suppress_line=2;
  658.             else
  659.                suppress_line=1;
  660.             endif
  661.           endif
  662.           ++ecursor;
  663.           if suppress_line == 1 then
  664.             ++ecursor;
  665.             if !eoc(ecursor) && Row_Positn == nextrow then
  666.               suppress_line=2;
  667.             endif
  668.             --ecursor;
  669.           endif
  670.         endif
  671.     endif
  672.     --ecursor;
  673. //
  674.     if suppress_line == 1 &&
  675.      (bandtype == Page_Header || bandtype == Page_Footer) then
  676.        plainopt(ecursor);
  677.     endif
  678.     if isnew then
  679.       isnew=0;  }
  680. ?? \
  681. {   else
  682.       if samerow then}
  683.  \
  684. {     else}
  685. ?? \
  686. {     endif
  687.     endif
  688.     if substr(Text_Item,1,1) == "\"" then
  689.       left_delimiter = "["
  690.       right_delimiter = "]"
  691.       delimit_flag = 1
  692.     endif
  693.     if suppress_line == 2 then}
  694. IIF(gl_plain,'' , \
  695. {   endif
  696.     if i > 70 then}
  697. ;
  698. {     separate(Text_Item);
  699.       if ni then}
  700. + {left_delimiter}{temp}{right_delimiter};
  701. {     endif
  702.     else}
  703. {left_delimiter}{Text_Item}{right_delimiter} \
  704. {   endif
  705.     if suppress_line == 2 then}
  706. ) \
  707. {     suppress_line=0;
  708.     endif
  709.     if delimit_flag then
  710.       left_delimiter="\""
  711.       right_delimiter="\""
  712.       delimit_flag=0
  713.     endif
  714.   @Box_Element:}
  715. DEFINE BOX FROM {(!BOX_LEFT) ? 0 : BOX_LEFT} TO \
  716. {((!BOX_LEFT) ? 0 : BOX_LEFT)+BOX_WIDTH-1} \
  717. HEIGHT {BOX_HEIGHT} \
  718. {   case BOX_TYPE of
  719.     0: // Single}
  720. SINGLE
  721. {   1: // Double}
  722. DOUBLE
  723. {   2: // Defined}
  724. CHR({BOX_SPECIAL_CHAR})
  725. {   endcase
  726.   @Page_Element:}
  727. EJECT PAGE
  728. { @Para_Element:}
  729. ?
  730. { @Ruler_Element:
  731. //
  732.     ++ecursor;
  733.     if ELEMENT_TYPE == @Para_Element then
  734.       loop
  735.     endif
  736.     --ecursor;
  737.     a=((!RULER_LEFTM) ? 0 : RULER_LEFTM);
  738.     x=((!RULER_INDENT) ? 0 : RULER_INDENT);
  739.     if x && x > 255 then
  740.       x = x - 65536;
  741.     endif
  742.     i=0;
  743.     if ruler_flag || (a != previous_lmargin && x != previous_indent) then
  744.       if a + previous_indent < 0 then
  745.         if x >= 0 then   }
  746. _indent={x}
  747. {         i=1;
  748.         else    }
  749. _indent=0
  750. {       endif
  751.       endif     }
  752. _lmargin={a}
  753. {     if !i then    }
  754. _indent={x}
  755. {     endif
  756.       previous_indent=x;
  757.       previous_lmargin=a;
  758.     else
  759.       if x != previous_indent then  }
  760. _indent={x}
  761. {       previous_indent=x;
  762.       endif
  763.       if a != previous_lmargin then }
  764. _lmargin={a}
  765. {       previous_lmargin=a;
  766.       endif
  767.     endif
  768.     a=RULER_RIGHTM;
  769.     if ruler_flag || a != previous_rmargin then }
  770. _rmargin={a}
  771. {     previous_rmargin=a;
  772.     endif}
  773. _pcolno={previous_lmargin+x }
  774. {   a=RULER_TABS;
  775.     if ruler_flag || a != previous_tabs then    }
  776. _tabs=\
  777. {     if LEN(a) > 70 then}
  778. ;
  779. {       separate(a);}
  780.  
  781. {     else}
  782. "{a}"
  783. {     endif
  784.       previous_tabs=a;
  785.     endif
  786.     ruler_flag=0;
  787. }
  788. { @Fld_Element:
  789. //
  790.     x=Col_Positn;
  791.     i=FLD_REPWIDTH;
  792.     ni=0;
  793.     pre_type=1;
  794.     if i > 237 then
  795.       foreach FLD_TEMPLATE fcursor in ecursor
  796.         if ni then
  797.           temp2=FLD_TEMPLATE;
  798.         endif
  799.         ++ni;
  800.       next
  801.     endif
  802.     current_column=x+i;
  803. //
  804.     set_combine_flag(ecursor)
  805. //
  806.     k=0;
  807.     x=0;
  808.     priv_vars2="";
  809.     if dBASE_III_PLUS == FIRST_GEN && FLD_VALUE_TYPE == CHARACTER_TYPE &&
  810.     (FLD_FIELDTYPE == Tabl_data || FLD_FIELDTYPE == Calc_data) then
  811.       priv_vars="TRIM(";
  812.       x=1;
  813.     else
  814.       priv_vars="";
  815.     endif
  816.   if retain_previous then
  817.       priv_vars="r_foot"+str(current_group_footer_field);
  818.   else
  819.     case FLD_FIELDTYPE of
  820.     Tabl_data:
  821. // With ALIAS
  822. //      priv_vars=priv_vars+upper_first(FLD_FILENAME)+"->"+
  823. //                          upper_first(FLD_FIELDNAME);
  824. // Without ALIAS
  825.       priv_vars=priv_vars+upper_first(FLD_FIELDNAME);
  826.     Calc_data:
  827.       if FLD_FIELDNAME then
  828.         priv_vars=priv_vars+lower(FLD_FIELDNAME);
  829.       else
  830.         foreach FLD_EXPRESSION fcursor in ecursor
  831.           if k then
  832.             priv_vars2=FLD_EXPRESSION;
  833.           endif
  834.           ++k;
  835.         next
  836.         if (UPPER(SUBSTR(LTRIM(FLD_EXPRESSION),1,5))) != "TRIM(" then
  837.           priv_vars=priv_vars+FLD_EXPRESSION;
  838.         else
  839.           priv_vars=FLD_EXPRESSION;
  840.           x=0;
  841.         endif
  842.       endif
  843.     Pred_data: ;
  844.       case FLD_PREDEFINE of
  845.       0: // Date
  846.         priv_vars="gd_date";
  847.       1: // Time
  848.         priv_vars="gc_time";
  849.       2: // Recno
  850.         priv_vars="RECNO()";
  851.       3: // Pageno
  852.         priv_vars="_pageno";
  853.       endcase
  854.     Summ_data:
  855.       if !FLD_FIELDNAME then
  856.         priv_vars="r_msum"+STR(xsum);
  857.       else
  858.         priv_vars=lower(FLD_FIELDNAME);
  859.       endif
  860.     endcase
  861.   endif
  862.     if x then
  863.       priv_vars2=priv_vars2+")";
  864.     endif
  865.     if !suppress_line &&
  866.     (bandtype == Page_Header || bandtype == Page_Footer) then
  867.       plainopt(ecursor);
  868.     endif
  869. //
  870. // For output of suppress repeated value memo fields
  871. //
  872.     if FLD_SUPPRESS && FLD_VALUE_TYPE == MEMO_TYPE then  }
  873.  
  874. lf_temp={suppress_repeated_values(ecursor);}
  875. {     isnew=1;
  876.     endif
  877.     if isnew then
  878.       isnew=0;  }
  879. ?? \
  880. {   else
  881.       if samerow then}
  882.  \
  883. {     else}
  884. ?? \
  885. {     endif
  886.     endif
  887.     if FLD_SUPPRESS && FLD_VALUE_TYPE == MEMO_TYPE then  }
  888. &lf_temp. \
  889. {   else
  890.       suppress_repeated_values(ecursor);
  891.     endif
  892.  
  893.     j=0;
  894.     if FLD_PICFUN then
  895.       temp=FLD_PICFUN;
  896.       j=AT("V",temp) | AT("H",temp);
  897.       if not j then}
  898. FUNCTION "{FLD_PICFUN}" \
  899. {     else
  900.         if not AT("H",temp) then
  901.           if j < LEN(FLD_PICFUN) then
  902.             temp=SUBSTR(temp,1,j)+STR(i)+SUBSTR(temp,j+1);
  903.           else
  904.             temp=temp+STR(i);
  905.           endif
  906.         endif}
  907. FUNCTION "{temp}" \
  908. {     endif
  909.     endif
  910.     temp=FLD_TEMPLATE+temp2;
  911.     if FLD_VALUE_TYPE == CHARACTER_TYPE then
  912.       if FLD_LENGTH == FLD_REPWIDTH && temp == REPLICATE("X",FLD_LENGTH) then
  913.         j=FLD_LENGTH;
  914.       endif
  915.     endif
  916.     if not j then
  917. //
  918. // test for invalid picture templates
  919. //
  920.       if temp && (FLD_FIELDTYPE != Pred_data || FLD_PREDEFINE != 1) &&
  921.       FLD_VALUE_TYPE != DATE_TYPE then
  922.         if i > 70 then}
  923. PICTURE ;
  924. {         separate(temp);
  925.         else}
  926. PICTURE "{FLD_TEMPLATE}" \
  927. {       endif
  928.       endif
  929.     endif
  930.   endcase
  931. //
  932. // Style of output ie. BOLD, UNDERLINE and ITALICS.
  933. //
  934.   if FLD_STYLE then}
  935. STYLE "\
  936. {   if Bold & FLD_STYLE then}
  937. B\
  938. {   endif
  939.     if Italic & FLD_STYLE then}
  940. I\
  941. {   endif
  942.     if Underline & FLD_STYLE then}
  943. U\
  944. {   endif
  945.     if Superscript & FLD_STYLE then}
  946. R\
  947. {   endif
  948.     if Subscript & FLD_STYLE then}
  949. L\
  950. {   endif
  951.     if User_Font & FLD_STYLE then
  952.       if  1 & FLD_STYLE then}1{endif}\
  953. {     if  2 & FLD_STYLE then}2{endif}\
  954. {     if  4 & FLD_STYLE then}3{endif}\
  955. {     if  8 & FLD_STYLE then}4{endif}\
  956. {     if 16 & FLD_STYLE then}5{endif}\
  957. {   endif}
  958. " \
  959. { endif
  960. //
  961. // List type is TEXT or FIELD?
  962. //
  963.   if (ELEMENT_TYPE == @Text_Element || ELEMENT_TYPE == @Fld_Element) then
  964. //
  965. // not a word wrap band?
  966. //
  967.     if !bandedit && first_combine then  }
  968. AT {Col_Positn}\
  969. {   endif
  970.     if Row_Positn != nextrow then   }
  971.  
  972. {     isnew=1;
  973.     else
  974.       if FLD_SUPPRESS && bsrv != xsrv then    }
  975. ,
  976. {       isnew=1;
  977.       else
  978.         if next_type && Row_Positn == nextrow then
  979.           ++samerow;
  980.           if samerow > 7 then  // Break ?? command every 8 expressions}
  981. ,
  982. {           isnew=1;
  983.             samerow=1;
  984.           else    }
  985. ,;
  986. {         endif
  987.         else    }
  988.  
  989. {         isnew=1;
  990.         endif
  991.       endif
  992.     endif
  993. //
  994.     if FLD_SUPPRESS && bsrv != xsrv then
  995.         assign_suppress_var(ecursor);
  996.     endif
  997. //
  998.     if first_combine && combine then
  999.       first_combine=0;
  1000.     endif
  1001.     if !combine && !first_combine then
  1002.       first_combine=1;
  1003.     endif
  1004. //
  1005.   endif
  1006. //
  1007.   if !optl_heading && bandtype == Page_Header then
  1008.     if maxrow == bandrow+1 && nextrow > bandrow+1 then
  1009.         output_optional_heading()
  1010.     endif
  1011.   endif
  1012. //
  1013.   if bandtype == Page_Header || bandtype == Page_Footer then
  1014.     x=0;
  1015.     if previous_row < maxrow && nextrow > maxrow &&
  1016.     FLD_FIELDTYPE == Pred_data &&
  1017.     (!FLD_PREDEFINE || FLD_PREDEFINE == 3) then
  1018.       x=1;
  1019.     endif
  1020.     if x || (suppress_line && nextrow > maxrow) then
  1021.       if suppress_line && nextrow > maxrow then suppress_line=0; endif
  1022. //
  1023.       if optl_heading && nextrow > maxrow && bandtype != Page_Footer then}
  1024. ?
  1025. {       ++maxrow;
  1026.         isnew=1;
  1027.       endif
  1028.       lmarg(1);}
  1029. ENDIF
  1030. {   endif
  1031.   endif
  1032. noprint:
  1033.   x=0;
  1034.   if ELEMENT_TYPE != @Ruler_Element then
  1035.     previous_row=Row_Positn;
  1036.   endif
  1037.   ++ecursor;
  1038. enddo
  1039. if inner_loop then --ecursor; endif
  1040. next ecursor;
  1041. //
  1042. // Output carriage returns for dBASE report to handle blank lines
  1043. //
  1044. nextline3:
  1045. if maxrow < bandhgt then
  1046.   if isopen then}
  1047. ?
  1048. { endif
  1049.   ++maxrow;
  1050.   goto nextline3;
  1051. endif
  1052. if bandtype == Report_Summary && is_rsumm_open then
  1053. }
  1054. gl_fandl=.F.
  1055. ?
  1056. RETURN
  1057. * EOP: Rsumm
  1058. {
  1059. endif
  1060. if bandtype == Page_Footer then
  1061.   finish_page_footer();
  1062. endif
  1063. return;
  1064. enddef
  1065.  
  1066. define upper_first(string)
  1067.         // Takes and returns a string with first letter upper case
  1068.         return upper( substr( string,1,1)) + lower( substr( string,2))
  1069. enddef
  1070.  
  1071. define separate(string);
  1072. //
  1073. // Separates strings longer than 70 so that printed output
  1074. // of the report does not cause truncation or line wrap.
  1075. //
  1076.     var x,y,length;
  1077.     x=1
  1078.     length=LEN(string)
  1079. moreleft:
  1080.     if x <= length then
  1081.         if x != 1 then  }
  1082. + \
  1083. {       endif
  1084.         if x+70 <= length then
  1085.             y=70
  1086.         else
  1087.             y=length-x+1
  1088.         endif;  }
  1089. {left_delimiter}{SUBSTR(string,x,y)}{right_delimiter};
  1090. {       x=x+70
  1091.         goto moreleft;
  1092.     endif
  1093.     return
  1094. enddef
  1095.  
  1096. define retain_previous_value(cursor)
  1097. //
  1098. // Test whether a footer field needs to ...
  1099. //
  1100.     var result;
  1101.     result=0;
  1102.     case cursor.FLD_FIELDTYPE of
  1103.     Tabl_data: result=1
  1104.     Pred_data:
  1105.         if cursor.FLD_PREDEFINE == 2 then
  1106.             result=1
  1107.         endif
  1108.     endcase
  1109.     return result
  1110. enddef
  1111.  
  1112. define set_combine_flag(cursor)
  1113. //
  1114. // Determine whether field and or text are touching.
  1115. // If they are, a trim is performed on the field.
  1116. //
  1117.     ++cursor;
  1118.     if cursor.ELEMENT_TYPE == @Text_Element
  1119.      || cursor.ELEMENT_TYPE == @Fld_Element then
  1120.         if current_column == cursor.Col_Positn
  1121.          && maxrow == cursor.Row_Positn then
  1122.             combine=1;
  1123.         else
  1124.             combine=0;
  1125.         endif
  1126.     endif
  1127.     --cursor;
  1128. enddef
  1129.  
  1130. define assign_suppress_var(cursor)}
  1131. IF .NOT. (r_msrv{xsrv} = \
  1132. //
  1133. {     if !cursor.FLD_FIELDNAME then
  1134.         if cursor.FLD_FIELDTYPE == Calc_data then}
  1135. {extend(cursor,@FLD_EXPRESSION)}
  1136. {       endif
  1137.         if cursor.FLD_FIELDTYPE == Summ_data then}
  1138. r_msum{xsum}\
  1139. {       endif
  1140.       else
  1141.         if cursor.FLD_VALUE_TYPE == MEMO_TYPE then}
  1142. LEFT({upper_first(cursor.FLD_FIELDNAME)},254)\
  1143. {       else
  1144.           if cursor.FLD_FIELDTYPE == Tabl_data then
  1145. upper_first(cursor.FLD_FIELDNAME)}
  1146. {         else
  1147. lower(cursor.FLD_FIELDNAME)}
  1148. {         endif
  1149.         endif
  1150.       endif}
  1151. )
  1152. {     if !cursor.FLD_FIELDNAME then}
  1153.    r_msrv{xsrv}=\
  1154. {       if cursor.FLD_FIELDTYPE == Calc_data then}
  1155. {extend(cursor,@FLD_EXPRESSION)}
  1156.  
  1157. {       endif
  1158.         if cursor.FLD_FIELDTYPE == Summ_data then}
  1159. r_msum{xsum}
  1160. {       endif
  1161.       else}
  1162.    r_msrv{xsrv}=\
  1163. {       if cursor.FLD_FIELDTYPE == Tabl_data then
  1164. upper_first(cursor.FLD_FIELDNAME)}
  1165.  
  1166. {       else
  1167. lower(cursor.FLD_FIELDNAME)}
  1168.  
  1169. {       endif
  1170.       endif}
  1171. ENDIF
  1172. {
  1173.     return;
  1174. enddef
  1175.  
  1176. define suppress_repeated_values(cursor)
  1177. //
  1178. // Suppress repeated values
  1179. //
  1180.     if cursor.FLD_SUPPRESS then}
  1181. IIF(\
  1182. //
  1183. // Date field?
  1184. //
  1185. {       if cursor.FLD_VALUE_TYPE == DATE_TYPE then}
  1186. DTOS(r_msrv{xsrv}) \
  1187. {       else}
  1188. r_msrv{xsrv} \
  1189. {       endif}
  1190. <> \
  1191. //
  1192. // Date field?
  1193. //
  1194. {       if cursor.FLD_VALUE_TYPE == DATE_TYPE then}
  1195. DTOS({priv_vars}{priv_vars2})\
  1196. {       else}
  1197. //
  1198. // Memo field?
  1199. //
  1200. {           if cursor.FLD_VALUE_TYPE == MEMO_TYPE then}
  1201. LEFT({priv_vars},254)\
  1202. {           else}
  1203. {priv_vars}{priv_vars2}
  1204. {           endif}
  1205. {       endif}
  1206. //
  1207. // Memo field?
  1208. //
  1209. {       if cursor.FLD_VALUE_TYPE == MEMO_TYPE then}
  1210. ,[{priv_vars}],[""])
  1211. {       else}
  1212. ,{priv_vars}{priv_vars2},"") \
  1213. {       endif
  1214.     else
  1215.  priv_vars}{priv_vars2} \
  1216. {   endif
  1217. enddef
  1218.  
  1219. define extend(elk,selno)
  1220.     var result;
  1221.     foreach selno j in elk
  1222.         result = result + j.selno
  1223.     next j
  1224.     return result
  1225. enddef
  1226.  
  1227. define plainopt(cursor)
  1228. //
  1229. // Strictly for Page headers and Page footers, suppresses
  1230. // page numbers and dates when the PLAIN option is used.
  1231. //
  1232.     var temp; temp=0
  1233.     if previous_row < maxrow && nextrow > maxrow
  1234.      && cursor.FLD_FIELDTYPE == Pred_data
  1235.      && (!cursor.FLD_PREDEFINE || cursor.FLD_PREDEFINE == 3) then
  1236.         temp=1
  1237.     endif
  1238.     if temp || suppress_line then   }
  1239. IF .NOT. gl_plain
  1240. {       lmarg(4);
  1241.     else
  1242.         if cursor.FLD_FIELDTYPE == Pred_data &&
  1243.          (!cursor.FLD_PREDEFINE || cursor.FLD_PREDEFINE == 3) then
  1244.             if !cursor.FLD_PREDEFINE then
  1245.                 priv_vars="IIF(gl_plain,'',gd_date)"
  1246.             else
  1247.                 priv_vars="IIF(gl_plain,'',_pageno)"
  1248.             endif
  1249.         endif
  1250.     endif
  1251.     return
  1252. enddef
  1253.  
  1254. define output_optional_heading()
  1255. //
  1256. // Where to place the HEADING parameter in the page header
  1257. //
  1258. }
  1259.  
  1260. *-- Print HEADING parameter - if it fits on line one
  1261. IF \
  1262. {if !suppress_line then}.NOT. gl_plain .AND. {endif}\
  1263. gn_length > 0 .AND. ll_heading
  1264.    ?? " "
  1265.    ?? gc_heading FUNCTION "I;V"+LTRIM(STR(ln_width-(_pcolno*2)))
  1266. ENDIF
  1267. {
  1268.     isnew=1;
  1269.     optl_heading=1;
  1270. enddef
  1271.  
  1272. define begin_new_band(cursor)
  1273. //
  1274. // Code output at the beginning of each band procedure
  1275. //
  1276.     band_previous=bandtype
  1277.     bandtype=cursor.BAND_BANDTYPE
  1278.     samerow=0
  1279.     combine=0
  1280.     first_combine=1
  1281.     ruler_flag=1;
  1282. //
  1283. // Output carriage returns for dBASE report to handle blank lines
  1284. //
  1285. nextline2:
  1286.     if maxrow < bandhgt then
  1287.         if isopen then  }
  1288. ?
  1289. {       endif
  1290.         ++maxrow;
  1291.         goto nextline2;
  1292.     endif
  1293.     if blankable_row then
  1294.         blankable_row=0;
  1295.         lmarg(1);   }
  1296. ENDIF
  1297. {   endif
  1298. //
  1299. // beyond the first band?
  1300. //
  1301.     if band_previous != 99 then
  1302. //
  1303.         if number_of_begin_new_pages && isopen then
  1304.             if band_previous == Group_Intro
  1305.              || band_previous == Detail
  1306.              || band_previous == Group_Summary then }
  1307. gl_newpage=.F.
  1308. {             if band_previous == Group_Intro ||
  1309.                  band_previous == Group_Summary then }
  1310. ?
  1311. {             endif
  1312.            endif
  1313.         endif
  1314.         if band_previous == Page_Header
  1315.          || band_previous == Page_Footer
  1316.          || isopen then
  1317.             case band_previous of
  1318.             Page_Header:
  1319.                 if suppress_line then
  1320.                     suppress_line=0
  1321.                     lmarg(1);   }
  1322. ENDIF
  1323. {               endif   }
  1324. //
  1325. {               if isopen
  1326.                  || (is_rintro_open && FRAME_PAGEHEADINGS)
  1327.                  || number_of_open_group_intros then    }
  1328. RETURN
  1329. * EOP: Pghead
  1330. {               endif
  1331.             Report_Intro:   }
  1332. RETURN
  1333. * EOP: Rintro
  1334. {           Group_Intro:    }
  1335. RETURN
  1336. {           Detail: }
  1337. RETURN
  1338. * EOP: __Detail
  1339. {           Group_Summary:
  1340.                 if dBASE_III_PLUS == FIRST_GEN then }
  1341. IF ln_level < 9{if cursor.GROUP == 96 then}6{else}7{endif}
  1342.    ?
  1343. ENDIF
  1344. {               endif   }
  1345. RETURN
  1346. {           Report_Summary: }
  1347. gl_fandl=.F.        && last page finished
  1348. ?
  1349. RETURN
  1350. * EOP: Rsumm
  1351. {           Page_Footer:
  1352.                 finish_page_footer();
  1353.             endcase
  1354.         endif   }
  1355.  
  1356. {   endif
  1357. //
  1358. // capture band attributes
  1359. // -----------------------
  1360. // bandrow and maxrow for row position
  1361. // bandedit for word wrap band
  1362. // isopen for band open or closed
  1363. //
  1364.     if cursor.Row_Positn then
  1365.         bandhgt=cursor.Row_Positn+cursor.BAND_HEIGHT+1
  1366.         bandrow=cursor.Row_Positn+1
  1367.         maxrow=cursor.Row_Positn+1
  1368.     else
  1369.         bandhgt=cursor.BAND_HEIGHT+1
  1370.         bandrow=1
  1371.         maxrow=1;
  1372.     endif
  1373.  
  1374.     bandedit=cursor.BAND_BANDEDIT
  1375.     bandgrp=cursor.GROUP
  1376.     bsrv=xsrv
  1377.     isnew=1
  1378.     isopen=cursor.BAND_OPENFLG;
  1379. //
  1380.     if cursor.BAND_BANDTYPE == Page_header
  1381.      || cursor.BAND_BANDTYPE == Page_Footer
  1382.      || cursor.BAND_OPENFLG then
  1383.         if cursor.BAND_BANDTYPE then   }
  1384. PROCEDURE \
  1385. {       else
  1386.             if cursor.BAND_OPENFLG
  1387.              || (is_rintro_open && FRAME_PAGEHEADINGS)
  1388.              || number_of_open_group_intros then    }
  1389. PROCEDURE \
  1390. {           endif
  1391.         endif
  1392.         case bandtype of
  1393.         Page_Header:
  1394.             if cursor.BAND_OPENFLG
  1395.              || (is_rintro_open && FRAME_PAGEHEADINGS)
  1396.              || number_of_open_group_intros then    }
  1397. Pghead
  1398. {               if line_one_length then }
  1399. PRIVATE ll_heading, ln_width
  1400. ll_heading = .T.
  1401. ln_width = _rmargin - _lmargin
  1402. {               endif
  1403.             endif
  1404.         Report_Intro:   }
  1405. Rintro
  1406. {       Group_Intro:    }
  1407. Head{cursor.GROUP}
  1408. {           if not cursor.BAND_INTROEACH then  }
  1409. IF gn_level=1
  1410.    RETURN
  1411. ENDIF
  1412. {           endif
  1413.             if dBASE_III_PLUS == FIRST_GEN && cursor.GROUP == 4
  1414.              && intro_band_one_height && intro_band_two_height then
  1415.                 ++bandhgt;
  1416.             else
  1417.                 if number_of_begin_new_pages && isopen then
  1418.                     --bandhgt;
  1419.                 endif
  1420.             endif
  1421.         Detail: }
  1422. __Detail
  1423. {       Group_Summary:  }
  1424. Foot{cursor.GROUP}
  1425. {           if dBASE_III_PLUS == FIRST_GEN then }
  1426. ln_lines=IIF(ln_level < 97, \
  1427. {               case cursor.GROUP of
  1428.                 96: }
  1429. {intro_band_one_height+intro_band_two_height+2}, \
  1430. {intro_band_one_height+intro_band_two_height+1})
  1431. {               95: }
  1432. {intro_band_two_height+2}, \
  1433. {intro_band_two_height+1})
  1434. {               endcase }
  1435. IF _plineno+ln_lines > gn_atline
  1436.    _plineno=gn_atline
  1437.    ?
  1438. ENDIF
  1439. {           else
  1440.                 if number_of_begin_new_pages && isopen then
  1441.                     --bandhgt;
  1442.                 endif
  1443.             endif
  1444.         Report_Summary: }
  1445. Rsumm
  1446. {           --bandhgt;
  1447.         Page_Footer:    }
  1448. Pgfoot
  1449. PRIVATE _box{if isopen}, _pspacing{endif}
  1450. gl_widow=.F.         && disable widow checking
  1451. {           if isopen then  }
  1452. _pspacing=1
  1453. ?
  1454. {           endif
  1455.             if bandhgt then --bandhgt endif
  1456.             if cursor.BAND_OPENFLG && cursor.BAND_HEIGHT then }
  1457. IF .NOT. gl_plain
  1458.    _pspacing=gn_pspace
  1459. {             lmarg(4);
  1460.             endif
  1461.         endcase
  1462.     endif
  1463. //
  1464. // is the band open?
  1465. // make system memvars PRIVATE
  1466. // only if the values change
  1467. //
  1468.     if isopen then
  1469. //
  1470. // BAND_NEWPAGE  - Begin band on new page:  No, Yes|
  1471. //
  1472.         if cursor.BAND_NEWPAGE then    }
  1473. IF .NOT. gl_newpage
  1474.    gl_newpage=.T.
  1475.    EJECT PAGE
  1476. ENDIF
  1477. {       endif
  1478. //
  1479. // BAND_TEXTPITCH - Text pitch for band:  Pica, Elite, Condensed, Default|
  1480. //
  1481.         if cursor.BAND_TEXTPITCH != 3 then }
  1482. IF SET("PRINT") = "ON" .AND. _ppitch <> {text_pitch(cursor.BAND_TEXTPITCH)}
  1483.    PRIVATE _ppitch
  1484.    _ppitch = {text_pitch(cursor.BAND_TEXTPITCH)}
  1485. ENDIF
  1486. {       endif
  1487. //
  1488. // BAND_QUALITY - Quality pitch for band:  Yes, No|
  1489. //
  1490.         if cursor.BAND_QUALITY < 2 then    }
  1491. IF SET("PRINT") = "ON" .AND. {if !cursor.BAND_QUALITY then}.NOT. {endif}_pquality
  1492.    PRIVATE _pquality
  1493.    _pquality = {if cursor.BAND_QUALITY then}.F.{else}.T.{endif}
  1494. ENDIF
  1495. {       endif
  1496. //
  1497. // BAND_SPACING - Default, single, double or triple
  1498. //
  1499.         if cursor.BAND_SPACING then    }
  1500. IF _pspacing <> {cursor.BAND_SPACING}
  1501.    PRIVATE _pspacing
  1502.    _pspacing={cursor.BAND_SPACING}
  1503. ENDIF
  1504. {       endif
  1505. //
  1506. // BAND_BANDEDIT - Wordwrap band:  Yes, No|
  1507. //
  1508.         if number_of_word_wrap_bands then
  1509.             if cursor.BAND_BANDEDIT then   }
  1510. PRIVATE _indent, _lmargin, _rmargin, _tabs
  1511. {           endif   }
  1512. IF {if cursor.BAND_BANDEDIT then}.NOT. {endif}_wrap
  1513.    PRIVATE _wrap
  1514.    _wrap = {if cursor.BAND_BANDEDIT then}.T.{else}.F.{endif}
  1515. ENDIF
  1516. {       endif
  1517. //
  1518.         ni="";
  1519.         if cursor.BAND_BANDTYPE == Detail then
  1520.             if cursor.BAND_HEIGHT then
  1521.                 if !bandspacing then
  1522.                     if cursor.BAND_HEIGHT > 1 then
  1523.                         ni=STR(cursor.BAND_HEIGHT)+" * gn_pspace";
  1524.                     else
  1525.                         ni="gn_pspace";
  1526.                     endif
  1527.                 else
  1528.                     if bandspacing > 1 then
  1529.                         ni=STR(cursor.BAND_HEIGHT * cursor.BAND_SPACING);
  1530.                     else
  1531.                         if cursor.BAND_HEIGHT > 1 then
  1532.                             ni=STR(cursor.BAND_HEIGHT);
  1533.                         endif
  1534.                     endif
  1535.                 endif
  1536.                 if ni then  }
  1537. IF {ni} < gn_atline - {tb_margin(bandlen2,bandspacing2)}
  1538.    IF gl_widow .AND. _plineno+{ni} > gn_atline + 1
  1539.       EJECT PAGE
  1540. {                      // kjn added number..open
  1541.                     if number_of_open_group_intros &&
  1542.                        number_of_group_intro_each then }
  1543.       gl_intros=.F.
  1544. {                   endif
  1545.                   lmarg(1);  }
  1546.    ENDIF
  1547. ENDIF
  1548. {               endif
  1549.             endif}
  1550. DO Upd_Vars
  1551. {           if number_of_begin_new_pages then   }
  1552. gl_newpage=.F.
  1553. {           endif
  1554.         endif
  1555.         if cursor.Row_Positn then previous_row=cursor.Row_Positn endif;
  1556.     endif
  1557.     return
  1558. enddef
  1559.  
  1560. define text_pitch(pitch_value)
  1561.     var result;
  1562.     case pitch_value of
  1563.     0: result="\"PICA\""
  1564.     1: result="\"ELITE\""
  1565.     2: result="\"CONDENSED\""
  1566.     3: result="\"DEFAULT\""
  1567.     endcase
  1568.     return result
  1569. enddef
  1570.  
  1571. define check4blank(incursor);
  1572. //
  1573. // This function determines whether or not a line is "blankable".
  1574. // A flag is set if the line contains text made up of only spaces
  1575. // or a numeric with a function Z which prints nothing for zero values
  1576. // or a character field.  It is only called for word wrap bands.
  1577. //
  1578.     var blank_line,fld_flag,j,k,previous_row,temp;
  1579.     k=incursor;
  1580.     blank_line=1;
  1581.     fld_flag=0;
  1582.     previous_row=k.Row_Positn;
  1583.  
  1584.     do while !eoc(k);
  1585.       if k.Row_Positn > previous_row then
  1586.         blank_line=fld_flag;
  1587.         exit;
  1588.       endif
  1589.       if blank_line then
  1590.         if k.FLD_VALUE_TYPE == 78 then
  1591.           if not AT("Z",k.FLD_PICFUN) then
  1592.             blank_line=0;
  1593.           else
  1594.             ++fld_flag;
  1595.           endif
  1596.         else
  1597.           if k.Text_Item then
  1598.             j=LEN(k.Text_Item);
  1599.             temp = k.Text_Item;
  1600.             if j == 237 then
  1601.               foreach Text_Item fcursor in k
  1602.                 j=j+LEN(fcursor.Text_Item);
  1603.                 temp = temp + fcursor.Text_Item;
  1604.               next
  1605.             endif
  1606.             if space(j) != temp then
  1607.               blank_line=0;
  1608.             endif
  1609.           else
  1610.             if k.ELEMENT_TYPE == @Fld_Element then
  1611.               if k.FLD_VALUE_TYPE != 67 then
  1612.                 blank_line=0;
  1613.               else
  1614.                 ++fld_flag;
  1615.               endif
  1616.             endif
  1617.           endif
  1618.         endif
  1619.       endif
  1620.       if !blank_line then
  1621.         exit;
  1622.       endif
  1623.       ++k;
  1624.     enddo
  1625.   return blank_line;
  1626. enddef
  1627.  
  1628. define conditional_if_for_blank_line(incursor);
  1629. //
  1630. // A dBASE IF statement is output for lines tested by check4blank()
  1631. // to test whether the printed line will contain only spaces.
  1632. //
  1633.     var field_flag, line_format, item_num, current_row, cursor2;
  1634.        cursor2=incursor;
  1635.        current_row=cursor2.Row_Positn;
  1636.        item_num=1;
  1637. }
  1638. *-- Test for blank line
  1639. PRIVATE tot_length
  1640. tot_length=0
  1641. tot_length=tot_length+LEN(TRIM( \
  1642. {
  1643.        do while !eoc(cursor2) && cursor2.Row_Positn == current_row}
  1644. {        if cursor2.ELEMENT_TYPE == @Fld_element then
  1645.            if field_flag then   }\
  1646. )) \
  1647. {            if line_format then    }
  1648.  
  1649. tot_length=tot_length+\
  1650. {              item_num=1;
  1651.              else
  1652.                if ++item_num <= 16 then   }\
  1653. + ;
  1654. {              else }
  1655.  
  1656. tot_length=tot_length+\
  1657. {                item_num=1;
  1658.                endif
  1659.              endif  }
  1660. LEN(TRIM( \
  1661. {          else
  1662.              field_flag=1;
  1663.            endif
  1664.          endif
  1665.          if cursor2.FLD_VALUE_TYPE == 78 then}
  1666. TRANSFORM(\
  1667. {          line_format = putfld(cursor2);}
  1668. ,"\
  1669. {          if cursor2.FLD_PICFUN then}
  1670. @{cursor2.FLD_PICFUN} \
  1671. {          endif}
  1672. {cursor2.FLD_TEMPLATE}") \
  1673. {//
  1674.          else
  1675.            if cursor2.ELEMENT_TYPE == @Fld_element then
  1676.              line_format = putfld(cursor2);
  1677.            endif
  1678.          endif
  1679.          ++cursor2;
  1680.        enddo}
  1681. ))
  1682. IF tot_length > 0
  1683. {  return 1;
  1684. enddef
  1685.  
  1686. define putfld(cursor);
  1687. //
  1688. // Subfunction of conditional_if_for_blank_line(), this places
  1689. // the individual fields on the same line as the IF statement.
  1690. //
  1691.     var retval,value,value2;
  1692.     retval=0;
  1693.     value=cursor.FLD_FIELDTYPE;
  1694.     case value of
  1695.     Tabl_data:
  1696.         if cursor.FLD_VALUE_TYPE == 77 then }
  1697. MLINE({upper_first(cursor.FLD_FIELDNAME)},1)\
  1698. {       else    }
  1699. {upper_first(cursor.FLD_FIELDNAME)}\
  1700. {       endif
  1701.     Calc_data:  }
  1702. {       if cursor.FLD_FIELDNAME then    }
  1703. {lower(cursor.FLD_FIELDNAME)}\
  1704. {       else
  1705.             foreach FLD_EXPRESSION exp in cursor    }
  1706. {FLD_EXPRESSION}\
  1707. {           next    }
  1708.  ;
  1709. {         retval=1;
  1710.         endif   }
  1711. {   Pred_data:
  1712.         value2=cursor.FLD_PREDEFINE;
  1713.         case value2 of
  1714.         0: // Date  }
  1715. gd_date\
  1716. {       1: // Time  }
  1717. gc_time\
  1718. {       2: // Recno }
  1719. RECNO()\
  1720. {       3: // Pageno}
  1721. _pageno\
  1722. {       endcase }
  1723. {   endcase }
  1724.  \
  1725. {   return retval;
  1726. enddef
  1727.  
  1728. define output_group_calls()
  1729.  
  1730.         if number_of_open_group_intros then }
  1731. *-- Process Group Intro bands during group breaks
  1732. PROCEDURE Grphead
  1733. IF EOF()
  1734.    RETURN
  1735. ENDIF
  1736. PRIVATE _pspacing
  1737. {           if bandspacing then }
  1738. _pspacing={bandspacing}
  1739. {           else    }
  1740. _pspacing=gn_pspace
  1741. {           endif   }
  1742. {       endif
  1743.         if dBASE_III_PLUS == FIRST_GEN
  1744.          && !number_of_open_group_summarys then   }
  1745. IF gn_level > 3
  1746.    ?
  1747. ENDIF
  1748. {       endif
  1749.         if number_of_open_group_intros then }
  1750. IF gn_level = 0
  1751.    gn_level=50
  1752. ENDIF
  1753. {       endif
  1754.         check4widows()
  1755.         if external_define then
  1756.             textopen(rptname+".grp")
  1757.         endif
  1758.         foreach BAND_ELEMENT k
  1759.             case BAND_BANDTYPE of
  1760.             Group_Intro:
  1761.                 if BAND_OPENFLG then    }
  1762. IF gn_level <= {GROUP}{if BAND_INTROEACH then} .OR. gl_intros{endif}
  1763.    DO Head{GROUP}
  1764. ENDIF
  1765. {               endif
  1766.             Detail:
  1767.                 if number_of_open_group_intros then }
  1768. gn_level=0
  1769. RETURN
  1770. * EOP: Grphead.PRG
  1771.  
  1772. {               endif
  1773.                 if number_of_open_group_summarys then   }
  1774. *-- Process Group Summary bands during group breaks
  1775. PROCEDURE Grpfoot
  1776. PARAMETER ln_level
  1777. {               endif
  1778.             Group_Summary:
  1779.                 if external_define then
  1780.                     textspos(0);
  1781.                     temp2=STR(GROUP)+": ";
  1782.                     if (temp = find_string(temp2) ) then }
  1783. IF ln_level >= {GROUP}
  1784. {                       lmarg(4);
  1785.     substr(temp,5)  }
  1786.  
  1787. {                       do while (temp = find_string(temp2) )    }
  1788. {   substr(temp,5)  }
  1789.  
  1790. {                       enddo
  1791.                         lmarg(0);   }
  1792. ENDIF
  1793. {                   endif
  1794.                 endif
  1795.                 if BAND_OPENFLG then    }
  1796. IF ln_level >= {GROUP}
  1797.    DO Foot{GROUP}
  1798. ENDIF
  1799. {               endif
  1800.             Page_Footer:
  1801.                 if number_of_open_group_summarys then   }
  1802. RETURN
  1803. * EOP: Grpfoot.PRG
  1804.  
  1805. {               endif
  1806.                 exit;
  1807.             endcase
  1808.         next k;
  1809.         if external_define then
  1810.             textclose()
  1811.         endif
  1812. enddef
  1813.  
  1814. define find_string(string)
  1815. //
  1816. // Assume the text file is open and rewound.  Matches are
  1817. // done on exact equality.  Returns entire string.
  1818. //
  1819.     var length,retval,temp; length=len(string); retval="";
  1820.  
  1821.     do while ( temp = textgetl() ) != EOF
  1822.         if string == substr(temp,1,length) then
  1823.             retval = temp;
  1824.             exit
  1825.         endif
  1826.     enddo
  1827.  
  1828.     return retval;
  1829. enddef
  1830.  
  1831. define check4widows()
  1832. //
  1833. // Check for possible widow band for group intros (includes detail length)
  1834. //
  1835.     foreach BAND_ELEMENT cursor
  1836.         if cursor.BAND_BANDTYPE == Group_Intro && cursor.BAND_OPENFLG then
  1837. //
  1838.             ni="";
  1839.             if !cursor.BAND_SPACING && !bandspacing then
  1840.                 ni=" * gn_pspace";
  1841.             else
  1842.                 if !cursor.BAND_SPACING && bandspacing > 1 then
  1843.                     ni=" * "+str(bandspacing);
  1844.                 else
  1845.                     if cursor.BAND_SPACING > 1 then
  1846.                         ni=" * "+str(cursor.BAND_SPACING);
  1847.                     endif
  1848.                 endif
  1849.             endif
  1850.             if cursor.BAND_HEIGHT > 1 then
  1851.                 a=str(cursor.BAND_HEIGHT)+ni+" ";
  1852.             else
  1853.                 if ni then
  1854.                     a=substr(ni,4)+" ";
  1855.                 else
  1856.                     a="";
  1857.                 endif
  1858.             endif   }
  1859. IF gn_level = {GROUP}
  1860. {           lmarg(4);
  1861.             if a then   }
  1862. IF {a} < gn_atline
  1863. {               lmarg(7);
  1864.             endif   }
  1865. IF (gl_widow .AND. _plineno+Gheight({cursor.GROUP}) > gn_atline + 1)\
  1866. {           if cursor.BAND_HEIGHT then}
  1867.  ;
  1868. .OR. (gl_widow .AND. _plineno+\
  1869. {               if cursor.BAND_HEIGHT > 1 then}
  1870. {cursor.BAND_HEIGHT}{ni}\
  1871. {               else
  1872.                     if !cursor.BAND_SPACING then
  1873.                         if ni then}
  1874. {SUBSTR(ni,4)}\
  1875. {                       else}
  1876. 1\
  1877. {                       endif
  1878.                     else}
  1879. {cursor.BAND_SPACING}\
  1880. {                   endif
  1881.                 endif}
  1882.  > gn_atline)
  1883. {           else}
  1884.  
  1885. {           endif}
  1886.    EJECT PAGE
  1887. ENDIF
  1888. {           if a then
  1889.                 lmarg(4);   }
  1890. ENDIF
  1891. {           endif
  1892.             lmarg(1);   }
  1893. ENDIF
  1894. {       endif
  1895.     next
  1896.     return
  1897. enddef
  1898.  
  1899. define reinit_page_variables()
  1900. //
  1901. // Summary fields set to Reset every page are assigned starting values.
  1902. //
  1903.     i=0
  1904.     x=0;
  1905.     foreach FLD_ELEMENT k
  1906.         if FLD_SUPPRESS then    }
  1907. r_msrv{++x}={init_not_value(k)}{logical_expression(k)}
  1908. {       endif
  1909.         if FLD_FIELDTYPE == Summ_data then
  1910.             if !FLD_FIELDNAME then
  1911.                 ++i
  1912.             endif
  1913.             if FLD_RESET == Each_Page then
  1914.                 if !FLD_FIELDNAME then
  1915.                     priv_vars="r_msum"+STR(i)
  1916.                 else
  1917.                     priv_vars=lower(FLD_FIELDNAME)
  1918.                 endif
  1919.                 sub_init_summary_vars(k)
  1920.             else
  1921.                 if FLD_OPERATION > SUM_OP then
  1922.                     xxsum = xxsum + 4
  1923.                 else
  1924.                     if FLD_OPERATION == AVERAGE_OP then
  1925.                         xxsum = xxsum + 2
  1926.                     endif
  1927.                 endif
  1928.             endif
  1929.         endif
  1930.     next k;
  1931.     xxsum=0
  1932.     return
  1933. enddef
  1934.  
  1935. define reinit_group_variables()
  1936. //
  1937. // Group break and summary fields are setup for next grouping.
  1938. //
  1939.     i=0
  1940.     x=0
  1941.     foreach FLD_ELEMENT k
  1942. //
  1943. // Summary field and reset on group?
  1944. //
  1945.         if FLD_FIELDTYPE == Summ_data then
  1946.             if !FLD_FIELDNAME then
  1947.                 ++x
  1948.             endif
  1949.             if FLD_RESET > Each_Group then
  1950.                 if i && i != FLD_RESET then
  1951.                     i=0
  1952.                     lmarg(1);   }
  1953. ENDIF
  1954. {               endif
  1955.                 if i != FLD_RESET then    }
  1956. IF gn_level <= {FLD_RESET}
  1957. {                   i=FLD_RESET
  1958.                     lmarg(4)
  1959.                 endif
  1960.                 if !FLD_FIELDNAME then
  1961.                     priv_vars="r_msum"+STR(x)
  1962.                 else
  1963.                     priv_vars=lower(FLD_FIELDNAME)
  1964.                 endif
  1965.                 sub_init_summary_vars(k)
  1966.             else
  1967.                 if FLD_OPERATION > SUM_OP then
  1968.                     xxsum = xxsum + 4
  1969.                 else
  1970.                     if FLD_OPERATION == AVERAGE_OP then
  1971.                         xxsum = xxsum + 2
  1972.                     endif
  1973.                 endif
  1974.             endif
  1975.         endif
  1976.     next k;
  1977.     xxsum=0
  1978.     if i then
  1979.         i=0
  1980.         lmarg(1);   }
  1981. ENDIF
  1982. {   endif
  1983.     foreach BAND_ELEMENT k
  1984.         if BAND_BANDTYPE == Group_Intro then    }
  1985. //
  1986. // Reset Group break vars on group intro bands
  1987. //
  1988. IF gn_level <= {GROUP}
  1989.    r_mvar{GROUP}={group_break_type(k)}
  1990. ENDIF
  1991. {       else
  1992.             if BAND_BANDTYPE > Group_Intro then
  1993.                 exit
  1994.             endif
  1995.         endif
  1996.     next k;
  1997.     return
  1998. enddef
  1999.  
  2000. define update_summary_and_calc_vars()
  2001. //
  2002. // This function is currently based on a calc all scenario.
  2003. // Which means all calculations happen in a left to right and
  2004. // top to bottom based on position in the report design surface.
  2005. //
  2006.     var temp;
  2007.     x=1
  2008.     xsum=0
  2009.     xxsum=0
  2010.     if external_define then
  2011.        textopen(rptname+".grp")
  2012.     endif
  2013.     foreach FLD_ELEMENT k
  2014.         case k.FLD_FIELDTYPE of
  2015. //
  2016. // Initialize named calculated fields for all bands
  2017. //
  2018.         Calc_data:
  2019.             if k.FLD_FIELDNAME && k.GROUP != 3 then}
  2020. {lower(k.FLD_FIELDNAME)}={
  2021.                 foreach FLD_EXPRESSION j in k
  2022.                     j.FLD_EXPRESSION}
  2023. {               next}
  2024.  
  2025. {           endif
  2026. //
  2027. // Summary fields
  2028. //
  2029.         Summ_data:
  2030.             if !FLD_FIELDNAME then
  2031.                 ++xsum
  2032.                 priv_vars="r_msum"+STR(xsum)
  2033.             else
  2034.                 priv_vars=lower(FLD_FIELDNAME);
  2035.             endif
  2036.             if external_define then
  2037.                 textspos(0);
  2038.                 if upd_find_string(priv_vars+"=") then
  2039.                     loop
  2040.                 endif
  2041.             endif
  2042.             case FLD_OPERATION of
  2043.             AVERAGE_OP: }
  2044. *-- Average
  2045. r_sum{++xxsum}=r_sum{xxsum}+1{tabto(40)}&& count
  2046. r_sum{++xxsum}=r_sum{xxsum}+{FLD_SUMFIELD}{tabto(40)}&& sum
  2047. {priv_vars}=r_sum{xxsum}/r_sum{xxsum-1}{tabto(40)}&& average
  2048. {           COUNT_OP:   }
  2049. *-- Count
  2050. {priv_vars}={priv_vars}+1
  2051. {           MAX_OP:     }
  2052. *-- Max
  2053. IF {FLD_SUMFIELD} > {priv_vars}
  2054.    {priv_vars}={FLD_SUMFIELD}
  2055. ENDIF
  2056. {           MIN_OP:     }
  2057. *-- Min
  2058. IF {FLD_SUMFIELD} < {priv_vars}
  2059.    {priv_vars}={FLD_SUMFIELD}
  2060. ENDIF
  2061. {           SUM_OP:     }
  2062. *-- Sum
  2063. {priv_vars}={priv_vars}+{FLD_SUMFIELD}
  2064. {           otherwise: // STD or VAR
  2065.                 if FLD_OPERATION == STD_DEV_OP then  }
  2066. *-- Std deviation
  2067. {               else    }
  2068. *-- Variance
  2069. {               endif   }
  2070. r_sum{++xxsum}=r_sum{xxsum}+{FLD_SUMFIELD}^2\
  2071. {tabto(40)}&& sum of squares
  2072. r_sum{++xxsum}=r_sum{xxsum}+{FLD_SUMFIELD}\
  2073. {tabto(40)}&& sum
  2074. r_sum{++xxsum}=r_sum{xxsum}+1\
  2075. {tabto(40)}&& count
  2076. r_sum{++xxsum}=r_sum{xxsum-2}/r_sum{xxsum-1}\
  2077. {tabto(40)}&& average
  2078. *-- variance
  2079. {priv_vars}=\
  2080. (r_sum{xxsum-3}+r_sum{xxsum-1}*(r_sum{xxsum}^2);
  2081.    -(2*r_sum{xxsum}*r_sum{xxsum-2}))/r_sum{xxsum-1}
  2082. {               if FLD_OPERATION == STD_DEV_OP then  }
  2083. {priv_vars}=SQRT({priv_vars})\
  2084. {tabto(40)}&& std deviation
  2085. {               endif
  2086.             endcase;
  2087.         otherwise:
  2088. //
  2089. // footer fields
  2090. //
  2091. // When a group break occurs the record pointer is positioned
  2092. // on the next group.  Therefore, it is neccessary to capture
  2093. // the values of the previous record into temporary variables.
  2094. //
  2095.             if GROUP > 50 then
  2096.                 retain_previous=0;
  2097.                 case k.FLD_FIELDTYPE of
  2098.                 Tabl_data: retain_previous=1;
  2099.                 Pred_data:
  2100.                         if k.FLD_PREDEFINE == 2 then
  2101.                             retain_previous=1;
  2102.                         endif
  2103.                 endcase
  2104.                 if retain_previous then
  2105.                     case FLD_FIELDTYPE of
  2106.                     Tabl_data:
  2107.                         temp = substr(FLD_FIELDNAME,1,1) +
  2108.                             lower(substr(FLD_FIELDNAME,2))
  2109.                     Pred_data:
  2110.                         temp = "RECNO()"
  2111.                     endcase;}
  2112. r_foot{x}={temp}
  2113. {                   ++x;
  2114.                 endif
  2115.             endif
  2116.         endcase
  2117.     next k;
  2118.     if external_define then
  2119.        textclose()
  2120.     endif
  2121.     xsum=0
  2122.     xxsum=0
  2123.     return
  2124. enddef
  2125.  
  2126. define upd_find_string(string)
  2127. //
  2128. // Assume the text file is open and rewound.  Matches are
  2129. // done on exact equality.  Determines whether string is found.
  2130. //
  2131.     var length,retval,temp; length=len(string); retval="";
  2132.  
  2133.     do while ( temp = textgetl() ) != EOF
  2134.         if string == substr(temp,5,length) then
  2135.             retval = "1";
  2136.             exit
  2137.         endif
  2138.     enddo
  2139.  
  2140.     return retval;
  2141. enddef
  2142.  
  2143. define output_proc_gheight()
  2144.     x=0
  2145.     foreach BAND_ELEMENT k
  2146.         if BAND_BANDTYPE > Group_Intro then
  2147.             exit
  2148.         endif
  2149.         if BAND_BANDTYPE == Group_Intro && BAND_OPENFLG then
  2150.             if !x then  }
  2151.  
  2152. *-- Determine height of group bands and detail band for widow checking
  2153. FUNCTION Gheight
  2154. PARAMETER Group_Band
  2155. retval=0              && return value
  2156. {           endif   }
  2157. IF Group_Band <= {GROUP}
  2158.    retval = retval +\
  2159. {           if BAND_HEIGHT > 1 then }
  2160.  {BAND_HEIGHT}\
  2161. {           endif
  2162.             if !BAND_SPACING && !bandspacing then
  2163.                 if BAND_HEIGHT > 1 then } *{endif}\
  2164.  gn_pspace
  2165. {           else
  2166.                 if !BAND_SPACING && bandspacing > 1 then
  2167.                     if BAND_HEIGHT > 1 then } *{endif}\
  2168.  {bandspacing}
  2169. {               else
  2170.                     if BAND_SPACING > 1 then
  2171.                         if BAND_HEIGHT > 1 then } *{endif}\
  2172.  {BAND_SPACING}
  2173. {                   else
  2174.                         if BAND_HEIGHT < 2 then }
  2175.  {BAND_HEIGHT}\
  2176. {                       endif   }
  2177.  
  2178. {                   endif
  2179.                 endif
  2180.             endif   }
  2181. ENDIF
  2182. {           ++x
  2183.         endif
  2184.     next k;
  2185.     if x then
  2186.         if bandlen50 then   }
  2187. *-- add height of detail band
  2188. retval = retval + \
  2189. {           if !bandspacing then    }
  2190. {               if bandlen50 > 1 then   }
  2191. {bandlen50} * \
  2192. {               endif   }
  2193. gn_pspace
  2194. {           else
  2195.                 if bandspacing > 1 then }
  2196. {bandspacing*bandlen50}
  2197.  
  2198. {               else}
  2199. {bandlen50}
  2200.  
  2201. {               endif
  2202.             endif
  2203.         endif   }
  2204. RETURN retval
  2205. * EOP: Gheight
  2206. {   endif
  2207.     return
  2208. enddef
  2209.  
  2210. define increment_group_by_record_vars()
  2211.     foreach BAND_ELEMENT k
  2212.         if BAND_BANDTYPE == Group_Intro then
  2213. //
  2214. // increment any group by record count vars.
  2215. //
  2216.             if BAND_GROUP_REC then  }
  2217. r_mvar{GROUP}=r_mvar{GROUP}+1
  2218. {           endif
  2219.         else
  2220.             if BAND_BANDTYPE > Group_Intro then
  2221.                 exit
  2222.             endif
  2223.         endif
  2224.     next k;
  2225.     return
  2226. enddef
  2227.  
  2228. define tb_margin(bandhgt,bandspc)
  2229.     var retval;
  2230. // Band set to default spacing
  2231.     if !bandspc then
  2232.  
  2233. // Detail band set to default
  2234.         if !bandspacing then
  2235.  
  2236. // Band height greater than 1
  2237.             if bandhgt > 1 then
  2238.                 retval="(_pspacing * "+STR(bandhgt)+" + 1)"
  2239.             else
  2240.                 if bandhgt then
  2241.                     retval="(_pspacing + 1)"
  2242.                 else
  2243.                     retval=1
  2244.                 endif
  2245.             endif
  2246.  
  2247. // Detail band is not default
  2248.         else
  2249.             retval=bandspacing * bandhgt +1
  2250.         endif
  2251.  
  2252. // Band is not default
  2253.     else
  2254.         retval=bandspc * bandhgt +1
  2255.     endif
  2256.     return retval
  2257. enddef
  2258.  
  2259. define build_case_statement()
  2260.     foreach BAND_ELEMENT k
  2261.         if BAND_BANDTYPE == Group_Intro then
  2262. //
  2263. // Group by field
  2264. //
  2265.             if BAND_GFIELD then }
  2266. CASE \
  2267. {               if at(">",BAND_GFIELD) then // Check for ALIAS
  2268. substr(BAND_GFIELD,at(">",BAND_GFIELD)+1)   }
  2269. {               else
  2270. BAND_GFIELD }
  2271. {               endif   }
  2272.  <> r_mvar{GROUP}
  2273. {           endif
  2274. //
  2275. // Group by expression
  2276. //
  2277.             if BAND_EXPRESSION then }
  2278. CASE (\
  2279. {               foreach BAND_EXPRESSION fcursor in k
  2280. BAND_EXPRESSION }
  2281. {               next    }
  2282. ) <> r_mvar{GROUP}
  2283. {           endif
  2284. //
  2285. // Group by record count
  2286. //
  2287.             if BAND_GROUP_REC then  }
  2288. CASE r_mvar{GROUP} > {BAND_GROUP_REC}
  2289. {           endif   }
  2290.    gn_level={GROUP}
  2291. {       endif
  2292.     next k;
  2293.     return
  2294. enddef
  2295.  
  2296. define init_group_footer_vars()
  2297.     x=0
  2298.     if number_of_group_footer_fields then
  2299.         x=1;    }
  2300. *-- Initialize group footer field variables
  2301. {       do while x <= number_of_group_footer_fields }
  2302. r_foot{x}=.F.
  2303. {           ++x;
  2304.         enddo   }
  2305.  
  2306. {   endif
  2307.     return
  2308. enddef
  2309.  
  2310. define init_calculated_vars()
  2311. //
  2312. // Initialize calculated fields.  This is neccesary since summary,
  2313. // calculated or group break variables might reference the field.
  2314. //
  2315.     x=0
  2316.     foreach FLD_ELEMENT k
  2317. //
  2318. // Reset Summary (on page) and Suppress repeated values
  2319. //
  2320.         if FLD_FIELDTYPE == Summ_data && FLD_RESET == 1 then
  2321.             ++number_of_reset_on_page
  2322.         endif
  2323.         if FLD_SUPPRESS then
  2324.             ++number_of_fld_suppress
  2325.         endif
  2326. //
  2327. // only if there is a fieldname assigned to the calculated field
  2328. //
  2329.         if FLD_FIELDTYPE == Calc_data && FLD_FIELDNAME then
  2330.             if !x then  }
  2331. *-- Initialize calculated variables.
  2332. {           endif
  2333. lower(FLD_FIELDNAME)}={get_init_val(FLD_VALUE_TYPE)}
  2334. {           ++x
  2335.         endif
  2336.     next k;
  2337.     return
  2338. enddef
  2339.  
  2340. define get_init_val(valtype)
  2341. //
  2342. // Called by init_calculated_vars()
  2343. //
  2344.     var result;
  2345.     case valtype of
  2346.     DATE_TYPE: result="CTOD(\"  /  /  \")"
  2347.     FLOAT_TYPE: result="FLOAT(0)"
  2348.     LOGICAL_TYPE: result=".F."
  2349.     NUMERIC_TYPE: result="0"
  2350.     otherwise: result="\"\""
  2351.     endcase
  2352.     return result
  2353. enddef
  2354.  
  2355. define init_group_break_vars()
  2356.     x=1  // to obtain number of group bands
  2357.     number_of_open_group_intros=0
  2358.  
  2359.     foreach BAND_ELEMENT k
  2360.         if BAND_BANDTYPE == Group_Intro then
  2361.             if x == 1 then  }
  2362. *-- Initialize group break vars.
  2363. {           endif
  2364.             if BAND_OPENFLG then
  2365.                 ++number_of_open_group_intros
  2366.             endif;  }
  2367. //
  2368. r_mvar{GROUP}={group_break_type(k)}
  2369. {           ++x
  2370.         endif
  2371.         if BAND_BANDTYPE == Detail then
  2372.             exit
  2373.         endif
  2374.     next k;
  2375.     maxgrp=x+2
  2376.     if x > 1 then   }
  2377.  
  2378. {   endif
  2379.     return
  2380. enddef
  2381.  
  2382. define group_break_type(cursor)
  2383. //
  2384. // Depending on type of group break e.g. Expression, Field or Record count
  2385. // assign the beginning value to the group break variable.
  2386. //
  2387.     var result;
  2388.     case cursor.BAND_GROUPTYPE of
  2389.     1: // by field
  2390.         if at(">",cursor.BAND_GFIELD) then  // Check for ALIAS
  2391.             result = substr(cursor.BAND_GFIELD,at(">",cursor.BAND_GFIELD)+1)
  2392.         else
  2393.             result = cursor.BAND_GFIELD
  2394.         endif
  2395.     3: // by record count
  2396.         result = "1"
  2397.     otherwise: // by expression
  2398.         foreach BAND_EXPRESSION j in cursor
  2399.             result = result + j.BAND_EXPRESSION
  2400.         next
  2401.     endcase
  2402.     return result
  2403. enddef
  2404.  
  2405. define init_summary_vars()
  2406. //
  2407. // Initialize summary fields, similar to calculated fields, it is
  2408. // necessary to assign "unrelated" starting values to these fields.
  2409. //
  2410.     x=0
  2411.     foreach FLD_ELEMENT k
  2412.         if FLD_FIELDTYPE == Summ_data then
  2413.             if !x then  }
  2414. *-- Initialize summary variables.
  2415. {           endif
  2416.             ++x
  2417.             if !FLD_FIELDNAME then
  2418.                 ++xsum
  2419.                 priv_vars="r_msum"+STR(xsum)
  2420.             else
  2421.                 priv_vars=lower(FLD_FIELDNAME)
  2422.             endif
  2423.             sub_init_summary_vars(k)
  2424.         endif
  2425.     next k;
  2426.     xsum=0
  2427.     xxsum=0
  2428.     if x then  }
  2429.  
  2430. {   endif
  2431.     return
  2432. enddef
  2433.  
  2434. define sub_init_summary_vars(cursor)
  2435. //
  2436. // Called by init_summary_vars() and reinit_group/page_variables()
  2437. // Set summary variables to starting values for next grouping.
  2438. //
  2439.     if cursor.FLD_OPERATION > SUM_OP then   }
  2440. STORE 0 TO r_sum{++xxsum},r_sum{++xxsum},\
  2441. r_sum{++xxsum},r_sum{++xxsum},{priv_vars}
  2442. {   else
  2443.         case cursor.FLD_OPERATION of
  2444.         AVERAGE_OP: }
  2445. STORE 0 TO r_sum{++xxsum},r_sum{++xxsum},{priv_vars}
  2446. {       COUNT_OP:   }
  2447. {priv_vars}=0
  2448. {       otherwise: // Min, Max or Sum
  2449.             if cursor.FLD_OPERATION == MIN_OP ||
  2450.                cursor.FLD_OPERATION == MAX_OP then
  2451.                 // ptr 63167 added MAX_OP}
  2452. {priv_vars}={cursor.FLD_SUMFIELD}
  2453. {           else    }
  2454. {priv_vars}=0
  2455. {           endif
  2456.         endcase
  2457.     endif
  2458.     return
  2459. enddef
  2460.  
  2461. define init_suppress_repeated_value_vars()
  2462.     x=0  // to offset each suppress repeated value variable
  2463. //
  2464.     foreach FLD_ELEMENT k
  2465. //
  2466. // suppress repeated values?
  2467. //
  2468.         if FLD_SUPPRESS then
  2469.             if !x then  }
  2470. *-- Initialize suppress repeated value variables.
  2471. {           endif   }
  2472. r_msrv{++x}={init_not_value(k)}{logical_expression(k)}
  2473. {       endif
  2474.     next k;
  2475.     if x then   }
  2476.  
  2477. {   endif
  2478.     return
  2479. enddef
  2480.  
  2481. define init_not_value(elk)
  2482. //
  2483. // Used assign a reverse value to suppress repeated value variables.
  2484. // Needed to print the first in the list of suppresed values.
  2485. //
  2486.     var result;
  2487.     case elk.FLD_VALUE_TYPE of
  2488.     DATE_TYPE: result ="CTOD(\"  /  /  \")"
  2489.     FLOAT_TYPE: result="FLOAT(0)"
  2490.     LOGICAL_TYPE: result=".NOT. "
  2491.     NUMERIC_TYPE: result="0"
  2492.     otherwise: result="\"\""
  2493.     endcase
  2494.     return result
  2495. enddef
  2496.  
  2497. define logical_expression(elk)
  2498. //
  2499. // If suppressed variable is of logical type the expression is returned
  2500. //
  2501.     var result;
  2502.     if elk.FLD_VALUE_TYPE != LOGICAL_TYPE then return "" endif
  2503.     if elk.FLD_FIELDNAME then
  2504.         if FLD_FIELDTYPE == Tabl_data then
  2505.             result=upper_first(elk.FLD_FIELDNAME)
  2506.         else
  2507.             result=lower(elk.FLD_FIELDNAME)
  2508.         endif
  2509.     else
  2510.         result=extend(elk,@FLD_EXPRESSION)
  2511.     endif
  2512.     return result
  2513. enddef
  2514.  
  2515. define assign_calculated_vars()
  2516. //
  2517. // Now the starting values for calculated fields are assigned.
  2518. // It could be a table, calculated or summary field (or any combination).
  2519. //
  2520.     x=0
  2521.     foreach FLD_ELEMENT k
  2522. //
  2523. // only if there is a fieldname assigned to the calculated field
  2524. //
  2525.         if FLD_FIELDTYPE == Calc_data && FLD_FIELDNAME then
  2526.             if !x then  }
  2527. *-- Assign initial values to calculated variables.
  2528. {           endif}
  2529. {lower(FLD_FIELDNAME)}={
  2530.                 foreach FLD_EXPRESSION j in k
  2531.                     j.FLD_EXPRESSION}
  2532. {               next}
  2533.  
  2534. {           ++x
  2535.         endif
  2536.     next k;
  2537.     if x then   }
  2538.  
  2539. {   endif
  2540.     return
  2541. enddef
  2542.  
  2543. define assign_summary_vars()
  2544. //
  2545. // This is synonymous with assign_calculated_vars.
  2546. //
  2547.     x=0
  2548.     foreach FLD_ELEMENT k
  2549.         if FLD_FIELDTYPE == Summ_data then
  2550.             if !FLD_FIELDNAME then
  2551.                 ++xsum
  2552.             endif
  2553.             if FLD_OPERATION == MAX_OP || FLD_OPERATION == MIN_OP then
  2554.                 if !x then  }
  2555. *-- Initialize min/max summary variables again,
  2556. *-- in case it's based on a calculated field.
  2557. {               endif
  2558.                 ++x
  2559.                 if !FLD_FIELDNAME then
  2560.                     priv_vars="r_msum"+STR(xsum)
  2561.                 else
  2562.                     priv_vars=lower(FLD_FIELDNAME)
  2563.                 endif;  }
  2564. {priv_vars}={FLD_SUMFIELD}
  2565. {           endif
  2566.         endif
  2567.     next k;
  2568.     xsum=0
  2569.     if x then   }
  2570.  
  2571. {   endif
  2572.     return
  2573. enddef
  2574.  
  2575. define finish_page_footer()
  2576. //
  2577. // Complete the bottom portion of the Page Footer band
  2578. //
  2579.     if suppress_line then
  2580.         suppress_line=0
  2581.         lmarg(1);   }
  2582. ENDIF
  2583. {   endif
  2584.     if isopen && bandhgt+1 then
  2585.       lmarg(1);  }
  2586. ENDIF
  2587. {   endif
  2588.     if demo_version then    }
  2589. ? "{demo_string}" FUNCTION "IV"+LTRIM(STR(_rmargin-_lmargin))
  2590. {   endif   }
  2591. EJECT PAGE
  2592. {   if number_of_group_intro_each then }
  2593. gl_intros=.T.
  2594. {   endif   }
  2595. {   if number_of_begin_new_pages then   }
  2596. gl_newpage=.T.
  2597. {   endif   }
  2598. *-- is the page number greater than the ending page
  2599. IF _pageno > _pepage
  2600.    GOTO BOTTOM
  2601.    SKIP
  2602.    gn_level=0
  2603. ENDIF
  2604. {   if number_of_reset_on_page || number_of_fld_suppress then   }
  2605. IF gl_fandl
  2606.    DO Pageinit
  2607. ENDIF
  2608. {   endif
  2609.     if has_headers() then
  2610.         if bandspacing then
  2611.             temp = bandspacing
  2612.         else
  2613.             temp = "gn_pspace"
  2614.         endif;  }
  2615. IF .NOT. gl_plain .AND. gl_fandl
  2616.    _pspacing={temp}
  2617.    DO Pghead
  2618. {     if number_of_group_intro_each then }
  2619.    IF gl_intros .AND. gn_level = 0
  2620.      DO GrpHead
  2621.      gl_newpage = .F.
  2622.      gl_intros = .F.
  2623.    ENDIF
  2624. {     endif   }
  2625. ENDIF
  2626. {   endif   }
  2627. RETURN
  2628. * EOP: Pgfoot
  2629. {   return
  2630. enddef
  2631.  
  2632. define has_headers()
  2633.     if is_page_header_open
  2634.      || (is_rintro_open && FRAME_PAGEHEADINGS)
  2635.      || number_of_open_group_intros then
  2636.         return 1
  2637.     else
  2638.         return 0
  2639.     endif
  2640. enddef
  2641.  
  2642. define pre_pass()
  2643. //
  2644. // Two passes are made thru the fields.  The first pass outputs a
  2645. // list of calculated fields to be used for lookup.  The next pass
  2646. // examines the "field to summarize on" attribute of summary fields
  2647. // and makes a list of those which reference the calc. fields.
  2648. //
  2649.     var xsum,xxsum,subgroup;
  2650.     external_define=0
  2651.     xsum=0
  2652.     xxsum=0
  2653.     number_of_group_calc_fields=0;
  2654.  
  2655.     create(rptname+".ord");
  2656.  
  2657.     foreach FLD_ELEMENT k
  2658.         if k.FLD_FIELDNAME && k.FLD_FIELDTYPE == Calc_data
  2659.         && k.GROUP > 3 && k.GROUP != 50 && k.GROUP < 97 then }
  2660. {k.FLD_FIELDNAME} = {if k.GROUP > 50 then k.GROUP else 100-k.GROUP endif}
  2661. {           ++number_of_group_calc_fields;
  2662.         endif
  2663.     next
  2664.     if number_of_group_calc_fields then
  2665.         create(rptname+".grp");
  2666.         textopen(rptname+".ord");
  2667.  
  2668.         foreach FLD_ELEMENT k
  2669.             if k.FLD_FIELDTYPE == Summ_data then
  2670.                 textspos(0);
  2671.                 if not ( subgroup=
  2672.                   pre_pass_find_string(k.FLD_SUMFIELD+" = ") ) then
  2673.                     subgroup = 50;
  2674.                 endif
  2675.                 if k.FLD_FIELDNAME then
  2676.                     priv_vars=lower(k.FLD_FIELDNAME);
  2677.                 else
  2678.                     ++xsum
  2679.                     priv_vars="r_msum"+STR(xsum);
  2680.                 endif
  2681.                 if subgroup != 50 then
  2682.                     if !external_define then
  2683.                         external_define=1;
  2684.                     endif
  2685.                     pre_pass_summary_field(k,subgroup);
  2686.                 endif
  2687.             endif
  2688.         next
  2689.  
  2690.         textclose();
  2691.     endif
  2692.     append(rptname+".FRG");
  2693.     fileerase(rptname+".ord");
  2694.     if not external_define then
  2695.         fileerase(rptname+".grp");
  2696.     endif
  2697.     return;
  2698. enddef
  2699.  
  2700. define pre_pass_find_string(string)
  2701. //
  2702. // Assume the text file is open and rewound.  Matches are
  2703. // done on exact equality, returns the right portion of the string.
  2704. //
  2705.     var length,retval,temp; length=len(string); retval="";
  2706.  
  2707.     do while ( temp = textgetl() ) != EOF
  2708.         if string == substr(temp,1,length) then
  2709.             retval = substr(temp,length+1);
  2710.             exit
  2711.         endif
  2712.     enddo
  2713.  
  2714.     return retval;
  2715. enddef
  2716.  
  2717. define pre_pass_summary_field(cursor,subgroup)
  2718. //
  2719. // Output a statement for the summary calculation to be included later.
  2720. //
  2721.     case cursor.FLD_OPERATION of
  2722.     AVERAGE_OP: }
  2723. {subgroup}: *-- Average
  2724. {subgroup}: r_sum{++xxsum}=r_sum{xxsum}+1{tabto(40)}&& count
  2725. {subgroup}: r_sum{++xxsum}=r_sum{xxsum}+{cursor.FLD_SUMFIELD}{tabto(40)}&& sum
  2726. {subgroup}: {priv_vars}=r_sum{xxsum}/r_sum{xxsum-1}{tabto(40)}&& average
  2727. {   COUNT_OP:   }
  2728. {subgroup}: *-- Count
  2729. {subgroup}: {priv_vars}={priv_vars}+1
  2730. {   MAX_OP:     }
  2731. {subgroup}: *-- Max
  2732. {subgroup}: IF {cursor.FLD_SUMFIELD} > {priv_vars}
  2733. {subgroup}:    {priv_vars}={cursor.FLD_SUMFIELD}
  2734. {subgroup}: ENDIF
  2735. {   MIN_OP:     }
  2736. {subgroup}: *-- Min
  2737. {subgroup}: IF {cursor.FLD_SUMFIELD} < {priv_vars}
  2738. {subgroup}:    {priv_vars}={cursor.FLD_SUMFIELD}
  2739. {subgroup}: ENDIF
  2740. {   SUM_OP:     }
  2741. {subgroup}: *-- Sum
  2742. {subgroup}: {priv_vars}={priv_vars}+{cursor.FLD_SUMFIELD}
  2743. {   otherwise: // STD or VAR
  2744.         if cursor.FLD_OPERATION == STD_DEV_OP then  }
  2745. {subgroup}: *-- Std deviation
  2746. {       else    }
  2747. {subgroup}: *-- Variance
  2748. {       endif   }
  2749. {subgroup}: r_sum{++xxsum}=r_sum{xxsum}+{cursor.FLD_SUMFIELD}^2\
  2750. {tabto(40)}&& sum of squares
  2751. {subgroup}: r_sum{++xxsum}=r_sum{xxsum}+{cursor.FLD_SUMFIELD}\
  2752. {tabto(40)}&& sum
  2753. {subgroup}: r_sum{++xxsum}=r_sum{xxsum}+1\
  2754. {tabto(40)}&& count
  2755. {subgroup}: r_sum{++xxsum}=r_sum{xxsum-2}/r_sum{xxsum-1}\
  2756. {tabto(40)}&& average
  2757. {subgroup}: *-- variance
  2758. {subgroup}: {priv_vars}=(r_sum{xxsum-3}+r_sum{xxsum-1}*(r_sum{xxsum}^2);
  2759. {subgroup}:    -(2*r_sum{xxsum}*r_sum{xxsum-2}))/r_sum{xxsum-1}
  2760. {       if cursor.FLD_OPERATION == STD_DEV_OP then  }
  2761. {subgroup}: {priv_vars}=SQRT({priv_vars})\
  2762. {tabto(40)}&& std deviation
  2763. {       endif
  2764.     endcase;
  2765. enddef
  2766.  
  2767. define report_setup()
  2768. var cursor, ntemp;
  2769.     foreach BAND_ELEMENT cursor
  2770.  
  2771.         if BAND_BANDEDIT then
  2772.             ++number_of_word_wrap_bands;
  2773.         endif
  2774.  
  2775.         if BAND_NEWPAGE then
  2776.             ++number_of_begin_new_pages;
  2777.         endif
  2778.  
  2779.         case BAND_BANDTYPE of
  2780.         Report_Intro:
  2781.             isrepo=1;
  2782.             if BAND_OPENFLG then
  2783.                 is_rintro_open = 1;
  2784.             endif
  2785.  
  2786.         Page_Header:
  2787.             if BAND_OPENFLG then
  2788.                 is_page_header_open = 1;
  2789.                 bandlen2=BAND_HEIGHT;
  2790.                 if BAND_SPACING then
  2791.                     bandspacing2=BAND_SPACING;
  2792.                 endif
  2793.             else
  2794.                 bandspacing2=1;
  2795.             endif
  2796.  
  2797.         Group_Intro:
  2798.             if dBASE_III_PLUS == FIRST_GEN then
  2799.                 if GROUP == 4 then
  2800.                     intro_band_one_height = BAND_HEIGHT;
  2801.                 endif
  2802.                 if GROUP == 5 then
  2803.                     intro_band_two_height = BAND_HEIGHT;
  2804.                 endif
  2805.             endif
  2806.             if BAND_INTROEACH then
  2807.                 ++number_of_group_intro_each;
  2808.             endif
  2809.  
  2810.         Detail:
  2811.             if BAND_OPENFLG then
  2812.                 bandlen50=BAND_HEIGHT;
  2813.             endif
  2814.             if BAND_SPACING then
  2815.                 bandspacing=BAND_SPACING;
  2816.             endif
  2817.  
  2818.         Group_Summary:
  2819.             if BAND_OPENFLG then
  2820.                 ++number_of_open_group_summarys;
  2821.             endif
  2822.  
  2823.         Page_Footer:
  2824.             if BAND_OPENFLG then
  2825.                 bandlen98=BAND_HEIGHT;
  2826.                 if BAND_SPACING then
  2827.                     bandspacing98=BAND_SPACING;
  2828.                 endif
  2829.             else
  2830.                 bandspacing98=1;
  2831.             endif
  2832.  
  2833.         Report_Summary:
  2834.             if BAND_OPENFLG then
  2835.                 is_rsumm_open = 1;
  2836.             endif
  2837.         endcase
  2838.     next
  2839.     if demo_version then
  2840.         ++bandlen98;
  2841.     endif
  2842.  
  2843.     if number_of_open_group_summarys || is_rsumm_open || bandlen98 then
  2844.         foreach FLD_ELEMENT cursor
  2845.             if GROUP > 50 then
  2846.                 retain_previous=0;
  2847.                 case cursor.FLD_FIELDTYPE of
  2848.                 Tabl_data: retain_previous=1;
  2849.                 Pred_data:
  2850.                         if cursor.FLD_PREDEFINE == 2 then
  2851.                             retain_previous=1;
  2852.                         endif
  2853.                 endcase
  2854.                 if retain_previous then
  2855.                     ++number_of_group_footer_fields;
  2856.                 endif
  2857.             endif
  2858.         next
  2859.     endif
  2860.     cursor = makec(@ELEMENT);
  2861.     ntemp = 1;
  2862.     do while ntemp
  2863.         if cursor.ELEMENT_TYPE == @Band_Element
  2864.          && cursor.BAND_BANDTYPE == Page_header then
  2865.             ntemp = 0;
  2866.         else
  2867.             ++cursor;
  2868.         endif
  2869.     enddo
  2870.     ntemp = ((!cursor.Row_Positn) ? 0 : cursor.Row_Positn)+2;
  2871.     ++cursor;
  2872.     do while cursor.Row_Positn <= ntemp
  2873.         if cursor.Row_Positn == ntemp then
  2874.             line_one_length = ((!cursor.Col_Positn) ? 0 : cursor.Col_Positn);
  2875.             case cursor.ELEMENT_TYPE of
  2876.             @Text_Element:
  2877.                 foreach Text_Item tcursor in cursor
  2878.                     line_one_length += len(Text_Item);
  2879.                 next
  2880.             @Fld_Element:
  2881.                 line_one_length += cursor.FLD_REPWIDTH;
  2882.             @Box_Element:
  2883.                 line_one_length +=
  2884.                  ((!cursor.BOX_LEFT) ? 0 : cursor.BOX_LEFT)
  2885.                  + cursor.BOX_WIDTH-1;
  2886.             endcase
  2887.         else
  2888.             exit
  2889.         endif
  2890.         ++cursor;
  2891.     enddo
  2892.     if line_one_length then
  2893.         ++line_one_length;
  2894.     endif
  2895.     return;
  2896. enddef
  2897.  
  2898. // EOP: REPORT.COD
  2899.  
  2900.